/// had zero roots.
const Type *MainRootRecordType;
public:
- LowerGC() : GCRootInt(0), GCReadInt(0), GCWriteInt(0),
+ LowerGC() : GCRootInt(0), GCReadInt(0), GCWriteInt(0),
GCRead(0), GCWrite(0), RootChain(0), MainRootRecordType(0) {}
virtual bool doInitialization(Module &M);
virtual bool runOnFunction(Function &F);
// If the program is using read/write barriers, find the implementations of
// them from the GC runtime library.
if (GCReadInt) // Make: sbyte* %llvm_gc_read(sbyte**)
- GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtrPtr, 0);
+ GCRead = M.getOrInsertFunction("llvm_gc_read", VoidPtr, VoidPtr, VoidPtrPtr, 0);
if (GCWriteInt) // Make: void %llvm_gc_write(sbyte*, sbyte**)
GCWrite = M.getOrInsertFunction("llvm_gc_write", Type::VoidTy,
- VoidPtr, VoidPtrPtr, 0);
+ VoidPtr, VoidPtr, VoidPtrPtr, 0);
// If the program has GC roots, get or create the global root list.
if (GCRootInt) {
if (RootChain == 0) {
// If the root chain does not exist, insert a new one with linkonce
// linkage!
- RootChain = new GlobalVariable(PRLTy, false, GlobalValue::LinkOnceLinkage,
- Constant::getNullValue(RootListTy),
+ RootChain = new GlobalVariable(PRLTy, false,
+ GlobalValue::LinkOnceLinkage,
+ Constant::getNullValue(PRLTy),
"llvm_gc_root_chain", &M);
} else if (RootChain->hasExternalLinkage() && RootChain->isExternal()) {
RootChain->setInitializer(Constant::getNullValue(PRLTy));
/// not have the specified type, insert a cast.
static void Coerce(Instruction *I, unsigned OpNum, Type *Ty) {
if (I->getOperand(OpNum)->getType() != Ty) {
- Constant *C = dyn_cast<Constant>(I->getOperand(OpNum));
- if (C && !isa<GlobalValue>(I->getOperand(OpNum)))
+ if (Constant *C = dyn_cast<Constant>(I->getOperand(OpNum)))
I->setOperand(OpNum, ConstantExpr::getCast(C, Ty));
else {
- CastInst *C = new CastInst(I->getOperand(OpNum), Ty, "", I);
- I->setOperand(OpNum, C);
+ CastInst *CI = new CastInst(I->getOperand(OpNum), Ty, "", I);
+ I->setOperand(OpNum, CI);
}
}
}
/// runOnFunction - If the program is using GC intrinsics, replace any
/// read/write intrinsics with the appropriate read/write barrier calls, then
-/// inline them. Finally, build the data structures for
+/// inline them. Finally, build the data structures for
bool LowerGC::runOnFunction(Function &F) {
// Quick exit for programs that are not using GC mechanisms.
if (!GCRootInt && !GCReadInt && !GCWriteInt) return false;
CI->setOperand(0, GCWrite);
// Insert casts of the operands as needed.
Coerce(CI, 1, VoidPtr);
- Coerce(CI, 2, VoidPtrPtr);
+ Coerce(CI, 2, VoidPtr);
+ Coerce(CI, 3, VoidPtrPtr);
} else {
- Coerce(CI, 1, VoidPtrPtr);
+ Coerce(CI, 1, VoidPtr);
+ Coerce(CI, 2, VoidPtrPtr);
if (CI->getType() == VoidPtr) {
CI->setOperand(0, GCRead);
} else {
// Create a whole new call to replace the old one.
CallInst *NC = new CallInst(GCRead, CI->getOperand(1),
+ CI->getOperand(2),
CI->getName(), CI);
Value *NV = new CastInst(NC, CI->getType(), "", CI);
CI->replaceAllUsesWith(NV);
MadeChange = true;
}
}
-
+
// If there are no GC roots in this function, then there is no need to create
// a GC list record for it.
if (GCRoots.empty()) return MadeChange;
Par[3] = Zero;
Value *RootPtrPtr = new GetElementPtrInst(AI, Par, "RootEntPtr", IP);
new StoreInst(Null, RootPtrPtr, IP);
-
+
// Each occurrance of the llvm.gcroot intrinsic now turns into an
// initialization of the slot with the address and a zeroing out of the
// address specified.
UnwindInst *UI = new UnwindInst(Cleanup);
PrevPtr = new LoadInst(PrevPtrPtr, "prevptr", UI);
new StoreInst(PrevPtr, RootChain, UI);
-
+
// Loop over all of the function calls, turning them into invokes.
while (!NormalCalls.empty()) {
CallInst *CI = NormalCalls.back();
// Remove the unconditional branch inserted at the end of the CBB.
CBB->getInstList().pop_back();
NewBB->getInstList().remove(CI);
-
+
// Create a new invoke instruction.
Value *II = new InvokeInst(CI->getCalledValue(), NewBB, Cleanup,
std::vector<Value*>(CI->op_begin()+1,