Fix 80 column violations.
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGISel.cpp
index 9e12a272ad6e4c6833ecdb3282bdae0e0fc54ab8..7702b3d5e90c096be026cec9fe6d076195458616 100644 (file)
@@ -54,14 +54,19 @@ using namespace llvm;
 static cl::opt<bool>
 EnableValueProp("enable-value-prop", cl::Hidden);
 static cl::opt<bool>
-EnableLegalizeTypes("enable-legalize-types", cl::Hidden);
+DisableLegalizeTypes("disable-legalize-types", cl::Hidden);
+#ifndef NDEBUG
 static cl::opt<bool>
 EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
-          cl::desc("Enable verbose messages in the experimental \"fast\" "
+          cl::desc("Enable verbose messages in the \"fast\" "
                    "instruction selector"));
 static cl::opt<bool>
 EnableFastISelAbort("fast-isel-abort", cl::Hidden,
           cl::desc("Enable abort calls when \"fast\" instruction fails"));
+#else
+static const bool EnableFastISelVerbose = false,
+                  EnableFastISelAbort = false;
+#endif
 static cl::opt<bool>
 SchedLiveInCopies("schedule-livein-copies",
                   cl::desc("Schedule copies of livein registers"),
@@ -119,7 +124,7 @@ ISHeuristic("pre-RA-sched",
                      " allocation):"));
 
 static RegisterScheduler
-defaultListDAGScheduler("default", "  Best scheduler for the target",
+defaultListDAGScheduler("default", "Best scheduler for the target",
                         createDefaultScheduler);
 
 namespace llvm {
@@ -314,7 +319,7 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
       // Mark landing pad.
       FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
 
-  SelectAllBasicBlocks(Fn, MF, MMI);
+  SelectAllBasicBlocks(Fn, MF, MMI, TII);
 
   // If the first basic block in the function has live ins that need to be
   // copied into vregs, emit the copies into the top of the block before
@@ -452,48 +457,6 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
                                         BasicBlock::iterator End) {
   SDL->setCurrentBasicBlock(BB);
 
-  MachineModuleInfo *MMI = CurDAG->getMachineModuleInfo();
-
-  if (MMI && BB->isLandingPad()) {
-    // Add a label to mark the beginning of the landing pad.  Deletion of the
-    // landing pad can thus be detected via the MachineModuleInfo.
-    unsigned LabelID = MMI->addLandingPad(BB);
-    CurDAG->setRoot(CurDAG->getLabel(ISD::EH_LABEL,
-                                     CurDAG->getEntryNode(), LabelID));
-
-    // Mark exception register as live in.
-    unsigned Reg = TLI.getExceptionAddressRegister();
-    if (Reg) BB->addLiveIn(Reg);
-
-    // Mark exception selector register as live in.
-    Reg = TLI.getExceptionSelectorRegister();
-    if (Reg) BB->addLiveIn(Reg);
-
-    // FIXME: Hack around an exception handling flaw (PR1508): the personality
-    // function and list of typeids logically belong to the invoke (or, if you
-    // like, the basic block containing the invoke), and need to be associated
-    // with it in the dwarf exception handling tables.  Currently however the
-    // information is provided by an intrinsic (eh.selector) that can be moved
-    // to unexpected places by the optimizers: if the unwind edge is critical,
-    // then breaking it can result in the intrinsics being in the successor of
-    // the landing pad, not the landing pad itself.  This results in exceptions
-    // not being caught because no typeids are associated with the invoke.
-    // This may not be the only way things can go wrong, but it is the only way
-    // we try to work around for the moment.
-    BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
-
-    if (Br && Br->isUnconditional()) { // Critical edge?
-      BasicBlock::iterator I, E;
-      for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
-        if (isa<EHSelectorInst>(I))
-          break;
-
-      if (I == E)
-        // No catch info found - try to extract some from the successor.
-        copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo);
-    }
-  }
-
   // Lower all of the non-terminator instructions.
   for (BasicBlock::iterator I = Begin; I != End; ++I)
     if (!isa<TerminatorInst>(I))
@@ -614,7 +577,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
   
   // Second step, hack on the DAG until it only uses operations and types that
   // the target supports.
-  if (EnableLegalizeTypes) {// Enable this some day.
+  if (!DisableLegalizeTypes) {
     if (ViewLegalizeTypesDAGs) CurDAG->viewGraph("legalize-types input for " +
                                                  BlockName);
 
@@ -708,7 +671,21 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
 }  
 
 void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
-                                            MachineModuleInfo *MMI) {
+                                            MachineModuleInfo *MMI,
+                                            const TargetInstrInfo &TII) {
+  // Initialize the Fast-ISel state, if needed.
+  FastISel *FastIS = 0;
+  if (EnableFastISel)
+    FastIS = TLI.createFastISel(*FuncInfo->MF, MMI,
+                                FuncInfo->ValueMap,
+                                FuncInfo->MBBMap,
+                                FuncInfo->StaticAllocaMap
+#ifndef NDEBUG
+                                , FuncInfo->CatchInfoLost
+#endif
+                                );
+
+  // Iterate over all basic blocks in the function.
   for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
     BasicBlock *LLVMBB = &*I;
     BB = FuncInfo->MBBMap[LLVMBB];
@@ -718,74 +695,132 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
     BasicBlock::iterator BI = Begin;
 
     // Lower any arguments needed in this block if this is the entry block.
-    if (LLVMBB == &Fn.getEntryBlock())
+    bool SuppressFastISel = false;
+    if (LLVMBB == &Fn.getEntryBlock()) {
       LowerArguments(LLVMBB);
 
-    // Before doing SelectionDAG ISel, see if FastISel has been requested.
-    // FastISel doesn't support EH landing pads, which require special handling.
-    if (EnableFastISel && !BB->isLandingPad()) {
-      if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, MMI,
-                                           FuncInfo->ValueMap,
-                                           FuncInfo->MBBMap,
-                                           FuncInfo->StaticAllocaMap)) {
-        // Emit code for any incoming arguments. This must happen before
-        // beginning FastISel on the entry block.
-        if (LLVMBB == &Fn.getEntryBlock()) {
-          CurDAG->setRoot(SDL->getControlRoot());
-          CodeGenAndEmitDAG();
-          SDL->clear();
-        }
-        F->setCurrentBlock(BB);
-        // Do FastISel on as many instructions as possible.
-        for (; BI != End; ++BI) {
-          // Just before the terminator instruction, insert instructions to
-          // feed PHI nodes in successor blocks.
-          if (isa<TerminatorInst>(BI))
-            if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, F)) {
-              if (EnableFastISelVerbose || EnableFastISelAbort) {
-                cerr << "FastISel miss: ";
-                BI->dump();
-              }
-              if (EnableFastISelAbort)
-                assert(0 && "FastISel didn't handle a PHI in a successor");
-              break;
-            }
-
-          // First try normal tablegen-generated "fast" selection.
-          if (F->SelectInstruction(BI))
-            continue;
-
-          // Next, try calling the target to attempt to handle the instruction.
-          if (F->TargetSelectInstruction(BI))
-            continue;
+      // If any of the arguments has the byval attribute, forgo
+      // fast-isel in the entry block.
+      if (FastIS) {
+        unsigned j = 1;
+        for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end();
+             I != E; ++I, ++j)
+          if (Fn.paramHasAttr(j, Attribute::ByVal)) {
+            if (EnableFastISelVerbose || EnableFastISelAbort)
+              cerr << "FastISel skips entry block due to byval argument\n";
+            SuppressFastISel = true;
+            break;
+          }
+      }
+    }
 
-          // Then handle certain instructions as single-LLVM-Instruction blocks.
-          if (isa<CallInst>(BI)) {
-            if (BI->getType() != Type::VoidTy) {
-              unsigned &R = FuncInfo->ValueMap[BI];
-              if (!R)
-                R = FuncInfo->CreateRegForValue(BI);
-            }
+    if (MMI && BB->isLandingPad()) {
+      // Add a label to mark the beginning of the landing pad.  Deletion of the
+      // landing pad can thus be detected via the MachineModuleInfo.
+      unsigned LabelID = MMI->addLandingPad(BB);
+
+      const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL);
+      BuildMI(BB, II).addImm(LabelID);
+
+      // Mark exception register as live in.
+      unsigned Reg = TLI.getExceptionAddressRegister();
+      if (Reg) BB->addLiveIn(Reg);
+
+      // Mark exception selector register as live in.
+      Reg = TLI.getExceptionSelectorRegister();
+      if (Reg) BB->addLiveIn(Reg);
+
+      // FIXME: Hack around an exception handling flaw (PR1508): the personality
+      // function and list of typeids logically belong to the invoke (or, if you
+      // like, the basic block containing the invoke), and need to be associated
+      // with it in the dwarf exception handling tables.  Currently however the
+      // information is provided by an intrinsic (eh.selector) that can be moved
+      // to unexpected places by the optimizers: if the unwind edge is critical,
+      // then breaking it can result in the intrinsics being in the successor of
+      // the landing pad, not the landing pad itself.  This results in exceptions
+      // not being caught because no typeids are associated with the invoke.
+      // This may not be the only way things can go wrong, but it is the only way
+      // we try to work around for the moment.
+      BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
+
+      if (Br && Br->isUnconditional()) { // Critical edge?
+        BasicBlock::iterator I, E;
+        for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
+          if (isa<EHSelectorInst>(I))
+            break;
 
-            SelectBasicBlock(LLVMBB, BI, next(BI));
-            continue;
-          }
+        if (I == E)
+          // No catch info found - try to extract some from the successor.
+          copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo);
+      }
+    }
 
-          // Otherwise, give up on FastISel for the rest of the block.
-          // For now, be a little lenient about non-branch terminators.
-          if (!isa<TerminatorInst>(BI) || isa<BranchInst>(BI)) {
+    // Before doing SelectionDAG ISel, see if FastISel has been requested.
+    if (FastIS && !SuppressFastISel) {
+      // Emit code for any incoming arguments. This must happen before
+      // beginning FastISel on the entry block.
+      if (LLVMBB == &Fn.getEntryBlock()) {
+        CurDAG->setRoot(SDL->getControlRoot());
+        CodeGenAndEmitDAG();
+        SDL->clear();
+      }
+      FastIS->startNewBlock(BB);
+      // Do FastISel on as many instructions as possible.
+      for (; BI != End; ++BI) {
+        // Just before the terminator instruction, insert instructions to
+        // feed PHI nodes in successor blocks.
+        if (isa<TerminatorInst>(BI))
+          if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, FastIS)) {
             if (EnableFastISelVerbose || EnableFastISelAbort) {
               cerr << "FastISel miss: ";
               BI->dump();
             }
             if (EnableFastISelAbort)
-              // The "fast" selector couldn't handle something and bailed.
-              // For the purpose of debugging, just abort.
-              assert(0 && "FastISel didn't select the entire block");
+              assert(0 && "FastISel didn't handle a PHI in a successor");
+            break;
+          }
+
+        // First try normal tablegen-generated "fast" selection.
+        if (FastIS->SelectInstruction(BI))
+          continue;
+
+        // Next, try calling the target to attempt to handle the instruction.
+        if (FastIS->TargetSelectInstruction(BI))
+          continue;
+
+        // Then handle certain instructions as single-LLVM-Instruction blocks.
+        if (isa<CallInst>(BI)) {
+          if (EnableFastISelVerbose || EnableFastISelAbort) {
+            cerr << "FastISel missed call: ";
+            BI->dump();
           }
-          break;
+
+          if (BI->getType() != Type::VoidTy) {
+            unsigned &R = FuncInfo->ValueMap[BI];
+            if (!R)
+              R = FuncInfo->CreateRegForValue(BI);
+          }
+
+          SelectBasicBlock(LLVMBB, BI, next(BI));
+          // If the instruction was codegen'd with multiple blocks,
+          // inform the FastISel object where to resume inserting.
+          FastIS->setCurrentBlock(BB);
+          continue;
         }
-        delete F;
+
+        // Otherwise, give up on FastISel for the rest of the block.
+        // For now, be a little lenient about non-branch terminators.
+        if (!isa<TerminatorInst>(BI) || isa<BranchInst>(BI)) {
+          if (EnableFastISelVerbose || EnableFastISelAbort) {
+            cerr << "FastISel miss: ";
+            BI->dump();
+          }
+          if (EnableFastISelAbort)
+            // The "fast" selector couldn't handle something and bailed.
+            // For the purpose of debugging, just abort.
+            assert(0 && "FastISel didn't select the entire block");
+        }
+        break;
       }
     }
 
@@ -797,6 +832,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
 
     FinishBasicBlock();
   }
+
+  delete FastIS;
 }
 
 void