Implement Transforms/InstCombine/cast-load-gep.ll, which allows us to devirtualize
[oota-llvm.git] / lib / Transforms / Scalar / LowerGC.cpp
index 0c03b91d55e0d21af36d38f7e3cffeff1de15ac1..b3463340c10c7cd51e500a4761065a589d21f4e4 100644 (file)
@@ -109,10 +109,10 @@ bool LowerGC::doInitialization(Module &M) {
   // 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) {
@@ -125,8 +125,9 @@ bool LowerGC::doInitialization(Module &M) {
     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));
@@ -143,8 +144,8 @@ static void Coerce(Instruction *I, unsigned OpNum, Type *Ty) {
     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);
     }
   }
 }
@@ -182,14 +183,17 @@ bool LowerGC::runOnFunction(Function &F) {
               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),
+                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);