further reduce the redundancy of types in the instruction encoding. This

shrinks function bodies in kc++ from 891913B to 884073B


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36817 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2007-05-06 00:21:25 +00:00
parent 7337ab9e92
commit abfbf85004
2 changed files with 77 additions and 84 deletions

View File

@ -1145,24 +1145,29 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
CurBB = FunctionBBs[0]; CurBB = FunctionBBs[0];
continue; continue;
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opcode, ty, opval, opval] case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
if (Record.size() < 4) return Error("Invalid BINOP record"); unsigned OpNum = 0;
const Type *Ty = getTypeByID(Record[1]); Value *LHS, *RHS;
int Opc = GetDecodedBinaryOpcode(Record[0], Ty); if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
Value *LHS = getFnValueByID(Record[2], Ty); getValue(Record, OpNum, LHS->getType(), RHS) ||
Value *RHS = getFnValueByID(Record[3], Ty); OpNum+1 != Record.size())
if (Opc == -1 || Ty == 0 || LHS == 0 || RHS == 0) return Error("Invalid BINOP record");
return Error("Invalid BINOP record");
int Opc = GetDecodedBinaryOpcode(Record[OpNum], LHS->getType());
if (Opc == -1) return Error("Invalid BINOP record");
I = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS); I = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS);
break; break;
} }
case bitc::FUNC_CODE_INST_CAST: { // CAST: [opcode, ty, opty, opval] case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
if (Record.size() < 4) return Error("Invalid CAST record"); unsigned OpNum = 0;
int Opc = GetDecodedCastOpcode(Record[0]); Value *Op;
const Type *ResTy = getTypeByID(Record[1]); if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
const Type *OpTy = getTypeByID(Record[2]); OpNum+2 != Record.size())
Value *Op = getFnValueByID(Record[3], OpTy); return Error("Invalid CAST record");
if (Opc == -1 || ResTy == 0 || OpTy == 0 || Op == 0)
const Type *ResTy = getTypeByID(Record[OpNum]);
int Opc = GetDecodedCastOpcode(Record[OpNum+1]);
if (Opc == -1 || ResTy == 0)
return Error("Invalid CAST record"); return Error("Invalid CAST record");
I = CastInst::create((Instruction::CastOps)Opc, Op, ResTy); I = CastInst::create((Instruction::CastOps)Opc, Op, ResTy);
break; break;
@ -1185,54 +1190,52 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
break; break;
} }
case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [ty, opval, opval, opval] case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval]
if (Record.size() < 4) return Error("Invalid SELECT record"); unsigned OpNum = 0;
const Type *Ty = getTypeByID(Record[0]); Value *TrueVal, *FalseVal, *Cond;
Value *Cond = getFnValueByID(Record[1], Type::Int1Ty); if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
Value *LHS = getFnValueByID(Record[2], Ty); getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
Value *RHS = getFnValueByID(Record[3], Ty); getValue(Record, OpNum, Type::Int1Ty, Cond))
if (Ty == 0 || Cond == 0 || LHS == 0 || RHS == 0)
return Error("Invalid SELECT record"); return Error("Invalid SELECT record");
I = new SelectInst(Cond, LHS, RHS);
I = new SelectInst(Cond, TrueVal, FalseVal);
break; break;
} }
case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval] case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval]
if (Record.size() < 3) return Error("Invalid EXTRACTELT record"); unsigned OpNum = 0;
const Type *OpTy = getTypeByID(Record[0]); Value *Vec, *Idx;
Value *Vec = getFnValueByID(Record[1], OpTy); if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
Value *Idx = getFnValueByID(Record[2], Type::Int32Ty); getValue(Record, OpNum, Type::Int32Ty, Idx))
if (OpTy == 0 || Vec == 0 || Idx == 0)
return Error("Invalid EXTRACTELT record"); return Error("Invalid EXTRACTELT record");
I = new ExtractElementInst(Vec, Idx); I = new ExtractElementInst(Vec, Idx);
break; break;
} }
case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval] case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval]
if (Record.size() < 4) return Error("Invalid INSERTELT record"); unsigned OpNum = 0;
const VectorType *OpTy = Value *Vec, *Elt, *Idx;
dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
if (OpTy == 0) return Error("Invalid INSERTELT record"); getValue(Record, OpNum,
Value *Vec = getFnValueByID(Record[1], OpTy); cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
Value *Elt = getFnValueByID(Record[2], OpTy->getElementType()); getValue(Record, OpNum, Type::Int32Ty, Idx))
Value *Idx = getFnValueByID(Record[3], Type::Int32Ty);
if (Vec == 0 || Elt == 0 || Idx == 0)
return Error("Invalid INSERTELT record"); return Error("Invalid INSERTELT record");
I = new InsertElementInst(Vec, Elt, Idx); I = new InsertElementInst(Vec, Elt, Idx);
break; break;
} }
case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [ty,opval,opval,opval] case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval]
if (Record.size() < 4) return Error("Invalid SHUFFLEVEC record"); unsigned OpNum = 0;
const VectorType *OpTy = Value *Vec1, *Vec2, *Mask;
dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
if (OpTy == 0) return Error("Invalid SHUFFLEVEC record"); getValue(Record, OpNum, Vec1->getType(), Vec2))
Value *Vec1 = getFnValueByID(Record[1], OpTy); return Error("Invalid SHUFFLEVEC record");
Value *Vec2 = getFnValueByID(Record[2], OpTy);
Value *Mask = getFnValueByID(Record[3], const Type *MaskTy =
VectorType::get(Type::Int32Ty, VectorType::get(Type::Int32Ty,
OpTy->getNumElements())); cast<VectorType>(Vec1->getType())->getNumElements());
if (Vec1 == 0 || Vec2 == 0 || Mask == 0)
if (getValue(Record, OpNum, MaskTy, Mask))
return Error("Invalid SHUFFLEVEC record"); return Error("Invalid SHUFFLEVEC record");
I = new ShuffleVectorInst(Vec1, Vec2, Mask); I = new ShuffleVectorInst(Vec1, Vec2, Mask);
break; break;
@ -1357,7 +1360,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
I = new UnreachableInst(); I = new UnreachableInst();
break; break;
case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, #ops, val0,bb0, ...] case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...]
if (Record.size() < 1 || ((Record.size()-1)&1)) if (Record.size() < 1 || ((Record.size()-1)&1))
return Error("Invalid PHI record"); return Error("Invalid PHI record");
const Type *Ty = getTypeByID(Record[0]); const Type *Ty = getTypeByID(Record[0]);
@ -1387,12 +1390,11 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
I = new MallocInst(Ty->getElementType(), Size, (1 << Align) >> 1); I = new MallocInst(Ty->getElementType(), Size, (1 << Align) >> 1);
break; break;
} }
case bitc::FUNC_CODE_INST_FREE: { // FREE: [opty, op] case bitc::FUNC_CODE_INST_FREE: { // FREE: [op, opty]
if (Record.size() < 2) unsigned OpNum = 0;
return Error("Invalid FREE record"); Value *Op;
const Type *OpTy = getTypeByID(Record[0]); if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
Value *Op = getFnValueByID(Record[1], OpTy); OpNum != Record.size())
if (!OpTy || !Op)
return Error("Invalid FREE record"); return Error("Invalid FREE record");
I = new FreeInst(Op); I = new FreeInst(Op);
break; break;
@ -1413,21 +1415,20 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
Value *Op; Value *Op;
if (getValueTypePair(Record, OpNum, NextValueNo, Op) || if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
OpNum+2 != Record.size()) OpNum+2 != Record.size())
return Error("Invalid RET record"); return Error("Invalid LOAD record");
I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1); I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1);
break; break;
} }
case bitc::FUNC_CODE_INST_STORE: { // STORE:[ptrty,val,ptr, align, vol] case bitc::FUNC_CODE_INST_STORE: { // STORE:[val, valty, ptr, align, vol]
if (Record.size() < 5) unsigned OpNum = 0;
return Error("Invalid LOAD record"); Value *Val, *Ptr;
const PointerType *OpTy = if (getValueTypePair(Record, OpNum, NextValueNo, Val) ||
dyn_cast_or_null<PointerType>(getTypeByID(Record[0])); getValue(Record, OpNum, PointerType::get(Val->getType()), Ptr) ||
Value *Op = getFnValueByID(Record[1], OpTy ? OpTy->getElementType() : 0); OpNum+2 != Record.size())
Value *Ptr = getFnValueByID(Record[2], OpTy);
if (!OpTy || !Op || !Ptr)
return Error("Invalid STORE record"); return Error("Invalid STORE record");
I = new StoreInst(Op, Ptr, Record[4], (1 << Record[3]) >> 1);
I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1);
break; break;
} }
case bitc::FUNC_CODE_INST_CALL: { // CALL: [cc, fnty, fnid, arg0, arg1...] case bitc::FUNC_CODE_INST_CALL: { // CALL: [cc, fnty, fnid, arg0, arg1...]

View File

@ -602,17 +602,15 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
default: default:
if (Instruction::isCast(I.getOpcode())) { if (Instruction::isCast(I.getOpcode())) {
Code = bitc::FUNC_CODE_INST_CAST; Code = bitc::FUNC_CODE_INST_CAST;
Vals.push_back(GetEncodedCastOpcode(I.getOpcode())); PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getTypeID(I.getType())); Vals.push_back(VE.getTypeID(I.getType()));
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); Vals.push_back(GetEncodedCastOpcode(I.getOpcode()));
Vals.push_back(VE.getValueID(I.getOperand(0)));
} else { } else {
assert(isa<BinaryOperator>(I) && "Unknown instruction!"); assert(isa<BinaryOperator>(I) && "Unknown instruction!");
Code = bitc::FUNC_CODE_INST_BINOP; Code = bitc::FUNC_CODE_INST_BINOP;
Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode())); PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getTypeID(I.getType()));
Vals.push_back(VE.getValueID(I.getOperand(0)));
Vals.push_back(VE.getValueID(I.getOperand(1))); Vals.push_back(VE.getValueID(I.getOperand(1)));
Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode()));
} }
break; break;
@ -623,28 +621,24 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break; break;
case Instruction::Select: case Instruction::Select:
Code = bitc::FUNC_CODE_INST_SELECT; Code = bitc::FUNC_CODE_INST_SELECT;
Vals.push_back(VE.getTypeID(I.getType())); PushValueAndType(I.getOperand(1), InstID, Vals, VE);
Vals.push_back(VE.getValueID(I.getOperand(0)));
Vals.push_back(VE.getValueID(I.getOperand(1)));
Vals.push_back(VE.getValueID(I.getOperand(2))); Vals.push_back(VE.getValueID(I.getOperand(2)));
Vals.push_back(VE.getValueID(I.getOperand(0)));
break; break;
case Instruction::ExtractElement: case Instruction::ExtractElement:
Code = bitc::FUNC_CODE_INST_EXTRACTELT; Code = bitc::FUNC_CODE_INST_EXTRACTELT;
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getValueID(I.getOperand(0)));
Vals.push_back(VE.getValueID(I.getOperand(1))); Vals.push_back(VE.getValueID(I.getOperand(1)));
break; break;
case Instruction::InsertElement: case Instruction::InsertElement:
Code = bitc::FUNC_CODE_INST_INSERTELT; Code = bitc::FUNC_CODE_INST_INSERTELT;
Vals.push_back(VE.getTypeID(I.getType())); PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getValueID(I.getOperand(0)));
Vals.push_back(VE.getValueID(I.getOperand(1))); Vals.push_back(VE.getValueID(I.getOperand(1)));
Vals.push_back(VE.getValueID(I.getOperand(2))); Vals.push_back(VE.getValueID(I.getOperand(2)));
break; break;
case Instruction::ShuffleVector: case Instruction::ShuffleVector:
Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; Code = bitc::FUNC_CODE_INST_SHUFFLEVEC;
Vals.push_back(VE.getTypeID(I.getType())); PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getValueID(I.getOperand(0)));
Vals.push_back(VE.getValueID(I.getOperand(1))); Vals.push_back(VE.getValueID(I.getOperand(1)));
Vals.push_back(VE.getValueID(I.getOperand(2))); Vals.push_back(VE.getValueID(I.getOperand(2)));
break; break;
@ -719,8 +713,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
case Instruction::Free: case Instruction::Free:
Code = bitc::FUNC_CODE_INST_FREE; Code = bitc::FUNC_CODE_INST_FREE;
Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getValueID(I.getOperand(0)));
break; break;
case Instruction::Alloca: case Instruction::Alloca:
@ -740,9 +733,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break; break;
case Instruction::Store: case Instruction::Store:
Code = bitc::FUNC_CODE_INST_STORE; Code = bitc::FUNC_CODE_INST_STORE;
Vals.push_back(VE.getTypeID(I.getOperand(1)->getType())); // Pointer PushValueAndType(I.getOperand(0), InstID, Vals, VE); // val.
Vals.push_back(VE.getValueID(I.getOperand(0))); // val. Vals.push_back(VE.getValueID(I.getOperand(1))); // ptr.
Vals.push_back(VE.getValueID(I.getOperand(1))); // ptr.
Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1); Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1);
Vals.push_back(cast<StoreInst>(I).isVolatile()); Vals.push_back(cast<StoreInst>(I).isVolatile());
break; break;