#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/OperandTraits.h"
using namespace llvm;
void BitcodeReader::FreeState() {
case 5: return GlobalValue::DLLImportLinkage;
case 6: return GlobalValue::DLLExportLinkage;
case 7: return GlobalValue::ExternalWeakLinkage;
+ case 8: return GlobalValue::CommonLinkage;
}
}
}
}
-
+namespace llvm {
namespace {
/// @brief A class for maintaining the slot number definition
/// as a placeholder for the actual definition for forward constants defs.
class ConstantPlaceHolder : public ConstantExpr {
ConstantPlaceHolder(); // DO NOT IMPLEMENT
void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
- Use Op;
public:
// allocate space for exactly one operand
void *operator new(size_t s) {
return User::operator new(s, 1);
}
explicit ConstantPlaceHolder(const Type *Ty)
- : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
- Op(UndefValue::get(Type::Int32Ty), this) {
+ : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) {
+ Op<0>() = UndefValue::get(Type::Int32Ty);
}
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};
}
+
+ // FIXME: can we inherit this from ConstantExpr?
+template <>
+struct OperandTraits<ConstantPlaceHolder> : FixedNumOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
+}
+
+void BitcodeReaderValueList::resize(unsigned Desired) {
+ if (Desired > Capacity) {
+ // Since we expect many values to come from the bitcode file we better
+ // allocate the double amount, so that the array size grows exponentially
+ // at each reallocation. Also, add a small amount of 100 extra elements
+ // each time, to reallocate less frequently when the array is still small.
+ //
+ Capacity = Desired * 2 + 100;
+ Use *New = allocHungoffUses(Capacity);
+ Use *Old = OperandList;
+ unsigned Ops = getNumOperands();
+ for (int i(Ops - 1); i >= 0; --i)
+ New[i] = Old[i].get();
+ OperandList = New;
+ if (Old) Use::zap(Old, Old + Ops, true);
+ }
+}
+
Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
const Type *Ty) {
if (Idx >= size()) {
// Insert a bunch of null values.
- Uses.resize(Idx+1);
- OperandList = &Uses[0];
+ resize(Idx + 1);
NumOperands = Idx+1;
}
- if (Value *V = Uses[Idx]) {
+ if (Value *V = OperandList[Idx]) {
assert(Ty == V->getType() && "Type mismatch in constant table!");
return cast<Constant>(V);
}
// Create and return a placeholder, which will later be RAUW'd.
Constant *C = new ConstantPlaceHolder(Ty);
- Uses[Idx].init(C, this);
+ OperandList[Idx].init(C, this);
return C;
}
Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) {
if (Idx >= size()) {
// Insert a bunch of null values.
- Uses.resize(Idx+1);
- OperandList = &Uses[0];
+ resize(Idx + 1);
NumOperands = Idx+1;
}
- if (Value *V = Uses[Idx]) {
+ if (Value *V = OperandList[Idx]) {
assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!");
return V;
}
// Create and return a placeholder, which will later be RAUW'd.
Value *V = new Argument(Ty);
- Uses[Idx].init(V, this);
+ OperandList[Idx].init(V, this);
return V;
}
if (Record.empty())
return Error("Invalid FLOAT record");
if (CurTy == Type::FloatTy)
- V = ConstantFP::get(CurTy, APFloat(APInt(32, (uint32_t)Record[0])));
+ V = ConstantFP::get(APFloat(APInt(32, (uint32_t)Record[0])));
else if (CurTy == Type::DoubleTy)
- V = ConstantFP::get(CurTy, APFloat(APInt(64, Record[0])));
+ V = ConstantFP::get(APFloat(APInt(64, Record[0])));
else if (CurTy == Type::X86_FP80Ty)
- V = ConstantFP::get(CurTy, APFloat(APInt(80, 2, &Record[0])));
+ V = ConstantFP::get(APFloat(APInt(80, 2, &Record[0])));
else if (CurTy == Type::FP128Ty)
- V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0]), true));
+ V = ConstantFP::get(APFloat(APInt(128, 2, &Record[0]), true));
else if (CurTy == Type::PPC_FP128Ty)
- V = ConstantFP::get(CurTy, APFloat(APInt(128, 2, &Record[0])));
+ V = ConstantFP::get(APFloat(APInt(128, 2, &Record[0])));
else
V = UndefValue::get(CurTy);
break;
if (OpTy->isFloatingPoint())
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
- else
+ else if (!isa<VectorType>(OpTy))
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
+ else if (OpTy->isFPOrFPVector())
+ V = ConstantExpr::getVFCmp(Record[3], Op0, Op1);
+ else
+ V = ConstantExpr::getVICmp(Record[3], Op0, Op1);
break;
}
case bitc::CST_CODE_INLINEASM: {
CurBB = FunctionBBs[0];
continue;
- case bitc::FUNC_CODE_INST_BB_UNWINDDEST: // BB_UNWINDDEST: [bb#]
- if (CurBB->getUnwindDest())
- return Error("Only permit one BB_UNWINDDEST per BB");
- if (Record.size() != 1)
- return Error("Invalid BB_UNWINDDEST record");
-
- CurBB->setUnwindDest(getBasicBlock(Record[0]));
- continue;
-
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
unsigned OpNum = 0;
Value *LHS, *RHS;
OpNum+1 != Record.size())
return Error("Invalid CMP record");
- if (LHS->getType()->isFPOrFPVector())
+ if (LHS->getType()->isFloatingPoint())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
- else
+ else if (!isa<VectorType>(LHS->getType()))
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
+ else if (LHS->getType()->isFPOrFPVector())
+ I = new VFCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
+ else
+ I = new VICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
break;
}
case bitc::FUNC_CODE_INST_GETRESULT: { // GETRESULT: [ty, val, n]
}
}
- I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops.begin(), Ops.end());
+ I = InvokeInst::Create(Callee, NormalBB, UnwindBB,
+ Ops.begin(), Ops.end());
cast<InvokeInst>(I)->setCallingConv(CCInfo);
cast<InvokeInst>(I)->setParamAttrs(PAL);
break;
if (!Ty) return Error("Invalid PHI record");
PHINode *PN = PHINode::Create(Ty);
- PN->reserveOperandSpace(Record.size()-1);
+ PN->reserveOperandSpace((Record.size()-1)/2);
for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
Value *V = getFnValueByID(Record[1+i], Ty);