Revamp the loop unroller, extending it to correctly update PHI nodes
[oota-llvm.git] / lib / CodeGen / Collector.cpp
index 67b392889e18681da5347fc79144949fab68a49c..6c5263d73e3b6f56428b8cedeede42ac4cb3e1f8 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Gordon Henriksen and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
@@ -35,10 +36,6 @@ namespace {
   /// directed by the Collector. It also performs automatic root initialization
   /// and custom intrinsic lowering.
   class VISIBILITY_HIDDEN LowerIntrinsics : public FunctionPass {
-    /// GCRootInt, GCReadInt, GCWriteInt - The function prototypes for the
-    /// llvm.gc* intrinsics.
-    Function *GCRootInt, *GCReadInt, *GCWriteInt;
-    
     static bool NeedsDefaultLoweringPass(const Collector &C);
     static bool NeedsCustomLoweringPass(const Collector &C);
     static bool CouldBecomeSafePoint(Instruction *I);
@@ -138,8 +135,7 @@ FunctionPass *llvm::createGCLoweringPass() {
 char LowerIntrinsics::ID = 0;
 
 LowerIntrinsics::LowerIntrinsics()
-  : FunctionPass((intptr_t)&ID),
-    GCRootInt(0), GCReadInt(0), GCWriteInt(0) {}
+  : FunctionPass((intptr_t)&ID) {}
 
 const char *LowerIntrinsics::getPassName() const {
   return "Lower Garbage Collection Instructions";
@@ -152,10 +148,6 @@ void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const {
 
 /// doInitialization - If this module uses the GC intrinsics, find them now.
 bool LowerIntrinsics::doInitialization(Module &M) {
-  GCReadInt  = M.getFunction("llvm.gcread");
-  GCWriteInt = M.getFunction("llvm.gcwrite");
-  GCRootInt  = M.getFunction("llvm.gcroot");
-  
   // FIXME: This is rather antisocial in the context of a JIT since it performs
   //        work against the entire module. But this cannot be done at
   //        runFunction time (initializeCustomLowering likely needs to change
@@ -186,8 +178,8 @@ bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots,
   SmallPtrSet<AllocaInst*,16> InitedRoots;
   for (; !CouldBecomeSafePoint(IP); ++IP)
     if (StoreInst *SI = dyn_cast<StoreInst>(IP))
-      if (AllocaInst *AI = dyn_cast<AllocaInst>(
-            IntrinsicInst::StripPointerCasts(SI->getOperand(1))))
+      if (AllocaInst *AI =
+          dyn_cast<AllocaInst>(SI->getOperand(1)->stripPointerCasts()))
         InitedRoots.insert(AI);
   
   // Add root initializers.
@@ -277,25 +269,35 @@ bool LowerIntrinsics::PerformDefaultLowering(Function &F, Collector &Coll) {
   bool MadeChange = false;
   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
     for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) {
-      if (CallInst *CI = dyn_cast<CallInst>(II++)) {
+      if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++)) {
         Function *F = CI->getCalledFunction();
-        if (F == GCWriteInt && LowerWr) {
-          // Replace a write barrier with a simple store.
-          Value *St = new StoreInst(CI->getOperand(1), CI->getOperand(3), CI);
-          CI->replaceAllUsesWith(St);
-          CI->eraseFromParent();
-        } else if (F == GCReadInt && LowerRd) {
-          // Replace a read barrier with a simple load.
-          Value *Ld = new LoadInst(CI->getOperand(2), "", CI);
-          Ld->takeName(CI);
-          CI->replaceAllUsesWith(Ld);
-          CI->eraseFromParent();
-        } else if (F == GCRootInt && InitRoots) {
-          // Initialize the GC root, but do not delete the intrinsic. The
-          // backend needs the intrinsic to flag the stack slot.
-          Roots.push_back(cast<AllocaInst>(
-            IntrinsicInst::StripPointerCasts(CI->getOperand(1))));
-        } else {
+        switch (F->getIntrinsicID()) {
+        case Intrinsic::gcwrite:
+          if (LowerWr) {
+            // Replace a write barrier with a simple store.
+            Value *St = new StoreInst(CI->getOperand(1), CI->getOperand(3), CI);
+            CI->replaceAllUsesWith(St);
+            CI->eraseFromParent();
+          }
+          break;
+        case Intrinsic::gcread:
+          if (LowerRd) {
+            // Replace a read barrier with a simple load.
+            Value *Ld = new LoadInst(CI->getOperand(2), "", CI);
+            Ld->takeName(CI);
+            CI->replaceAllUsesWith(Ld);
+            CI->eraseFromParent();
+          }
+          break;
+        case Intrinsic::gcroot:
+          if (InitRoots) {
+            // Initialize the GC root, but do not delete the intrinsic. The
+            // backend needs the intrinsic to flag the stack slot.
+            Roots.push_back(cast<AllocaInst>(
+                              CI->getOperand(1)->stripPointerCasts()));
+          }
+          break;
+        default:
           continue;
         }
         
@@ -335,7 +337,7 @@ void MachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
 unsigned MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, 
                                      MachineBasicBlock::iterator MI) const {
   unsigned Label = MMI->NextLabelID();
-  BuildMI(MBB, MI, TII->get(TargetInstrInfo::LABEL)).addImm(Label);
+  BuildMI(MBB, MI, TII->get(TargetInstrInfo::LABEL)).addImm(Label).addImm(2);
   return Label;
 }
 
@@ -357,7 +359,7 @@ void MachineCodeAnalysis::FindSafePoints(MachineFunction &MF) {
                                  BBE = MF.end(); BBI != BBE; ++BBI)
     for (MachineBasicBlock::iterator MI = BBI->begin(),
                                      ME = BBI->end(); MI != ME; ++MI)
-      if (TII->isCall(MI->getOpcode()))
+      if (MI->getDesc().isCall())
         VisitCallPoint(*MI);
 }