forked from OSchip/llvm-project
For PR950:
Update for signless integer types and parameter attribute implementation. Of significant note: 1. This changes the bytecode format yet again. 2. There are 1/2 as many integer type planes (this is a good thing) 3. GEP indices now use only 1 bit to identify their type which means more GEP instructions won't be relegated to format 0 (size win) 4. Parameter attributes are implemented but currently being stored verbosely for each function type. Some other day this needs to be optimized for size. llvm-svn: 32783
This commit is contained in:
parent
42f0cbe769
commit
b46895bc1f
|
@ -44,7 +44,7 @@ namespace {
|
|||
Use Op;
|
||||
ConstantPlaceHolder(const Type *Ty)
|
||||
: ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
|
||||
Op(UndefValue::get(Type::IntTy), this) {
|
||||
Op(UndefValue::get(Type::Int32Ty), this) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
if (Oprnds.size() != 2)
|
||||
error("Invalid extractelement instruction!");
|
||||
Value *V1 = getValue(iType, Oprnds[0]);
|
||||
Value *V2 = getValue(Type::UIntTyID, Oprnds[1]);
|
||||
Value *V2 = getValue(Type::Int32TyID, Oprnds[1]);
|
||||
|
||||
if (!ExtractElementInst::isValidOperands(V1, V2))
|
||||
error("Invalid extractelement instruction!");
|
||||
|
@ -587,7 +587,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
|
||||
Value *V1 = getValue(iType, Oprnds[0]);
|
||||
Value *V2 = getValue(getTypeSlot(PackedTy->getElementType()),Oprnds[1]);
|
||||
Value *V3 = getValue(Type::UIntTyID, Oprnds[2]);
|
||||
Value *V3 = getValue(Type::Int32TyID, Oprnds[2]);
|
||||
|
||||
if (!InsertElementInst::isValidOperands(V1, V2, V3))
|
||||
error("Invalid insertelement instruction!");
|
||||
|
@ -601,7 +601,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
Value *V1 = getValue(iType, Oprnds[0]);
|
||||
Value *V2 = getValue(iType, Oprnds[1]);
|
||||
const PackedType *EltTy =
|
||||
PackedType::get(Type::UIntTy, PackedTy->getNumElements());
|
||||
PackedType::get(Type::Int32Ty, PackedTy->getNumElements());
|
||||
Value *V3 = getValue(getTypeSlot(EltTy), Oprnds[2]);
|
||||
if (!ShuffleVectorInst::isValidOperands(V1, V2, V3))
|
||||
error("Invalid shufflevector instruction!");
|
||||
|
@ -713,7 +713,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
case Instruction::AShr:
|
||||
Result = new ShiftInst(Instruction::OtherOps(Opcode),
|
||||
getValue(iType, Oprnds[0]),
|
||||
getValue(Type::UByteTyID, Oprnds[1]));
|
||||
getValue(Type::Int8TyID, Oprnds[1]));
|
||||
break;
|
||||
case Instruction::Ret:
|
||||
if (Oprnds.size() == 0)
|
||||
|
@ -876,7 +876,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
error("Invalid malloc instruction!");
|
||||
|
||||
Result = new MallocInst(cast<PointerType>(InstTy)->getElementType(),
|
||||
getValue(Type::UIntTyID, Oprnds[0]), Align);
|
||||
getValue(Type::Int32TyID, Oprnds[0]), Align);
|
||||
break;
|
||||
}
|
||||
case Instruction::Alloca: {
|
||||
|
@ -889,7 +889,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
error("Invalid alloca instruction!");
|
||||
|
||||
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
|
||||
getValue(Type::UIntTyID, Oprnds[0]), Align);
|
||||
getValue(Type::Int32TyID, Oprnds[0]), Align);
|
||||
break;
|
||||
}
|
||||
case Instruction::Free:
|
||||
|
@ -913,18 +913,16 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
|||
unsigned IdxTy = 0;
|
||||
// Struct indices are always uints, sequential type indices can be
|
||||
// any of the 32 or 64-bit integer types. The actual choice of
|
||||
// type is encoded in the low two bits of the slot number.
|
||||
// type is encoded in the low bit of the slot number.
|
||||
if (isa<StructType>(TopTy))
|
||||
IdxTy = Type::UIntTyID;
|
||||
IdxTy = Type::Int32TyID;
|
||||
else {
|
||||
switch (ValIdx & 3) {
|
||||
switch (ValIdx & 1) {
|
||||
default:
|
||||
case 0: IdxTy = Type::UIntTyID; break;
|
||||
case 1: IdxTy = Type::IntTyID; break;
|
||||
case 2: IdxTy = Type::ULongTyID; break;
|
||||
case 3: IdxTy = Type::LongTyID; break;
|
||||
case 0: IdxTy = Type::Int32TyID; break;
|
||||
case 1: IdxTy = Type::Int64TyID; break;
|
||||
}
|
||||
ValIdx >>= 2;
|
||||
ValIdx >>= 1;
|
||||
}
|
||||
Idx.push_back(getValue(IdxTy, ValIdx));
|
||||
NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true);
|
||||
|
@ -1159,17 +1157,23 @@ const Type *BytecodeReader::ParseType() {
|
|||
switch (PrimType) {
|
||||
case Type::FunctionTyID: {
|
||||
const Type *RetType = readType();
|
||||
unsigned RetAttr = read_vbr_uint();
|
||||
|
||||
unsigned NumParams = read_vbr_uint();
|
||||
|
||||
std::vector<const Type*> Params;
|
||||
while (NumParams--)
|
||||
std::vector<FunctionType::ParameterAttributes> Attrs;
|
||||
Attrs.push_back(FunctionType::ParameterAttributes(RetAttr));
|
||||
while (NumParams--) {
|
||||
Params.push_back(readType());
|
||||
if (Params.back() != Type::VoidTy)
|
||||
Attrs.push_back(FunctionType::ParameterAttributes(read_vbr_uint()));
|
||||
}
|
||||
|
||||
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
|
||||
if (isVarArg) Params.pop_back();
|
||||
|
||||
Result = FunctionType::get(RetType, Params, isVarArg);
|
||||
Result = FunctionType::get(RetType, Params, isVarArg, Attrs);
|
||||
break;
|
||||
}
|
||||
case Type::ArrayTyID: {
|
||||
|
@ -1399,9 +1403,9 @@ Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
|
|||
break;
|
||||
}
|
||||
|
||||
case Type::UByteTyID: // Unsigned integer types...
|
||||
case Type::UShortTyID:
|
||||
case Type::UIntTyID: {
|
||||
case Type::Int8TyID: // Unsigned integer types...
|
||||
case Type::Int16TyID:
|
||||
case Type::Int32TyID: {
|
||||
unsigned Val = read_vbr_uint();
|
||||
if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
|
||||
error("Invalid unsigned byte/short/int read.");
|
||||
|
@ -1410,23 +1414,14 @@ Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
|
|||
break;
|
||||
}
|
||||
|
||||
case Type::ULongTyID:
|
||||
Result = ConstantInt::get(Ty, read_vbr_uint64());
|
||||
if (Handler) Handler->handleConstantValue(Result);
|
||||
break;
|
||||
|
||||
case Type::SByteTyID: // Signed integer types...
|
||||
case Type::ShortTyID:
|
||||
case Type::IntTyID:
|
||||
case Type::LongTyID: {
|
||||
int64_t Val = read_vbr_int64();
|
||||
case Type::Int64TyID: {
|
||||
uint64_t Val = read_vbr_uint64();
|
||||
if (!ConstantInt::isValueValidForType(Ty, Val))
|
||||
error("Invalid signed byte/short/int/long read.");
|
||||
error("Invalid constant integer read.");
|
||||
Result = ConstantInt::get(Ty, Val);
|
||||
if (Handler) Handler->handleConstantValue(Result);
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::FloatTyID: {
|
||||
float Val;
|
||||
read_float(Val);
|
||||
|
@ -1542,8 +1537,8 @@ void BytecodeReader::ParseStringConstants(unsigned NumEntries, ValueTable &Tab){
|
|||
error("String constant data invalid!");
|
||||
|
||||
const ArrayType *ATy = cast<ArrayType>(Ty);
|
||||
if (ATy->getElementType() != Type::SByteTy &&
|
||||
ATy->getElementType() != Type::UByteTy)
|
||||
if (ATy->getElementType() != Type::Int8Ty &&
|
||||
ATy->getElementType() != Type::Int8Ty)
|
||||
error("String constant data invalid!");
|
||||
|
||||
// Read character data. The type tells us how long the string is.
|
||||
|
|
|
@ -145,8 +145,7 @@ void SlotCalculator::processModule() {
|
|||
//
|
||||
for (unsigned plane = 0, e = Table.size(); plane != e; ++plane) {
|
||||
if (const ArrayType *AT = dyn_cast<ArrayType>(Types[plane]))
|
||||
if (AT->getElementType() == Type::SByteTy ||
|
||||
AT->getElementType() == Type::UByteTy) {
|
||||
if (AT->getElementType() == Type::Int8Ty) {
|
||||
TypePlane &Plane = Table[plane];
|
||||
unsigned FirstNonStringID = 0;
|
||||
for (unsigned i = 0, e = Plane.size(); i != e; ++i)
|
||||
|
|
|
@ -214,16 +214,20 @@ void BytecodeWriter::outputType(const Type *T) {
|
|||
int Slot = Table.getSlot(MT->getReturnType());
|
||||
assert(Slot != -1 && "Type used but not available!!");
|
||||
output_typeid((unsigned)Slot);
|
||||
output_vbr(unsigned(MT->getParamAttrs(0)));
|
||||
|
||||
// Output the number of arguments to function (+1 if varargs):
|
||||
output_vbr((unsigned)MT->getNumParams()+MT->isVarArg());
|
||||
|
||||
// Output all of the arguments...
|
||||
FunctionType::param_iterator I = MT->param_begin();
|
||||
unsigned Idx = 1;
|
||||
for (; I != MT->param_end(); ++I) {
|
||||
Slot = Table.getSlot(*I);
|
||||
assert(Slot != -1 && "Type used but not available!!");
|
||||
output_typeid((unsigned)Slot);
|
||||
output_vbr(unsigned(MT->getParamAttrs(Idx)));
|
||||
Idx++;
|
||||
}
|
||||
|
||||
// Terminate list with VoidTy if we are a varargs function...
|
||||
|
@ -323,20 +327,13 @@ void BytecodeWriter::outputConstant(const Constant *CPV) {
|
|||
output_vbr(0U);
|
||||
break;
|
||||
|
||||
case Type::UByteTyID: // Unsigned integer types...
|
||||
case Type::UShortTyID:
|
||||
case Type::UIntTyID:
|
||||
case Type::ULongTyID:
|
||||
case Type::Int8TyID: // Unsigned integer types...
|
||||
case Type::Int16TyID:
|
||||
case Type::Int32TyID:
|
||||
case Type::Int64TyID:
|
||||
output_vbr(cast<ConstantInt>(CPV)->getZExtValue());
|
||||
break;
|
||||
|
||||
case Type::SByteTyID: // Signed integer types...
|
||||
case Type::ShortTyID:
|
||||
case Type::IntTyID:
|
||||
case Type::LongTyID:
|
||||
output_vbr(cast<ConstantInt>(CPV)->getSExtValue());
|
||||
break;
|
||||
|
||||
case Type::ArrayTyID: {
|
||||
const ConstantArray *CPA = cast<ConstantArray>(CPV);
|
||||
assert(!CPA->isString() && "Constant strings should be handled specially!");
|
||||
|
@ -489,12 +486,10 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
|||
unsigned IdxId;
|
||||
switch (I->getOperand(Idx)->getType()->getTypeID()) {
|
||||
default: assert(0 && "Unknown index type!");
|
||||
case Type::UIntTyID: IdxId = 0; break;
|
||||
case Type::IntTyID: IdxId = 1; break;
|
||||
case Type::ULongTyID: IdxId = 2; break;
|
||||
case Type::LongTyID: IdxId = 3; break;
|
||||
case Type::Int32TyID: IdxId = 0; break;
|
||||
case Type::Int64TyID: IdxId = 1; break;
|
||||
}
|
||||
Slot = (Slot << 2) | IdxId;
|
||||
Slot = (Slot << 1) | IdxId;
|
||||
}
|
||||
output_vbr(unsigned(Slot));
|
||||
}
|
||||
|
@ -742,12 +737,10 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
|||
unsigned IdxId;
|
||||
switch (GEP->getOperand(Idx)->getType()->getTypeID()) {
|
||||
default: assert(0 && "Unknown index type!");
|
||||
case Type::UIntTyID: IdxId = 0; break;
|
||||
case Type::IntTyID: IdxId = 1; break;
|
||||
case Type::ULongTyID: IdxId = 2; break;
|
||||
case Type::LongTyID: IdxId = 3; break;
|
||||
case Type::Int32TyID: IdxId = 0; break;
|
||||
case Type::Int64TyID: IdxId = 1; break;
|
||||
}
|
||||
Slots[Idx] = (Slots[Idx] << 2) | IdxId;
|
||||
Slots[Idx] = (Slots[Idx] << 1) | IdxId;
|
||||
if (Slots[Idx] > MaxOpSlot) MaxOpSlot = Slots[Idx];
|
||||
}
|
||||
} else if (Opcode == 58) {
|
||||
|
|
Loading…
Reference in New Issue