For inline asm output operand that matches an input. Encode the input operand index...
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAGISel.cpp
index 744ea00acea9483ecbe34f3fce279bc47aa4f78b..fdabd4cb25e61d36d6abdaadd7e90e550a408878 100644 (file)
@@ -12,8 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "isel"
-#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "ScheduleDAGSDNodes.h"
 #include "SelectionDAGBuild.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Constants.h"
 #include "llvm/CallingConv.h"
@@ -33,7 +34,7 @@
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
+#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/DwarfWriter.h"
@@ -51,8 +52,6 @@
 #include <algorithm>
 using namespace llvm;
 
-static cl::opt<bool>
-EnableValueProp("enable-value-prop", cl::Hidden);
 static cl::opt<bool>
 DisableLegalizeTypes("disable-legalize-types", cl::Hidden);
 #ifndef NDEBUG
@@ -136,20 +135,17 @@ namespace llvm {
   //===--------------------------------------------------------------------===//
   /// createDefaultScheduler - This creates an instruction scheduler appropriate
   /// for the target.
-  ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
-                                      SelectionDAG *DAG,
-                                      const TargetMachine *TM,
-                                      MachineBasicBlock *BB,
-                                      bool Fast) {
+  ScheduleDAGSDNodes* createDefaultScheduler(SelectionDAGISel *IS,
+                                             bool Fast) {
     const TargetLowering &TLI = IS->getTargetLowering();
 
     if (Fast)
-      return createFastDAGScheduler(IS, DAG, TM, BB, Fast);
+      return createFastDAGScheduler(IS, Fast);
     if (TLI.getSchedulingPreference() == TargetLowering::SchedulingForLatency)
-      return createTDListDAGScheduler(IS, DAG, TM, BB, Fast);
+      return createTDListDAGScheduler(IS, Fast);
     assert(TLI.getSchedulingPreference() ==
          TargetLowering::SchedulingForRegPressure && "Unknown sched type!");
-    return createBURRListDAGScheduler(IS, DAG, TM, BB, Fast);
+    return createBURRListDAGScheduler(IS, Fast);
   }
 }
 
@@ -159,7 +155,7 @@ namespace llvm {
 // insert.  The specified MachineInstr is created but not inserted into any
 // basic blocks, and the scheduler passes ownership of it to this method.
 MachineBasicBlock *TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
-                                                       MachineBasicBlock *MBB) {
+                                                 MachineBasicBlock *MBB) const {
   cerr << "If a target marks an instruction with "
        << "'usesCustomDAGSchedInserter', it must implement "
        << "TargetLowering::EmitInstrWithCustomInserter!\n";
@@ -191,9 +187,9 @@ static void EmitLiveInCopy(MachineBasicBlock *MBB,
   // don't coalesce. Also, only coalesce away a virtual register to virtual
   // register copy.
   bool Coalesced = false;
-  unsigned SrcReg, DstReg;
+  unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
   if (NumUses == 1 &&
-      TII.isMoveInstr(*UseMI, SrcReg, DstReg) &&
+      TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
       TargetRegisterInfo::isVirtualRegister(DstReg)) {
     VirtReg = DstReg;
     Coalesced = true;
@@ -266,11 +262,11 @@ static void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
 // SelectionDAGISel code
 //===----------------------------------------------------------------------===//
 
-SelectionDAGISel::SelectionDAGISel(TargetLowering &tli, bool fast) :
-  FunctionPass(&ID), TLI(tli),
+SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, bool fast) :
+  FunctionPass(&ID), TM(tm), TLI(*tm.getTargetLowering()),
   FuncInfo(new FunctionLoweringInfo(TLI)),
   CurDAG(new SelectionDAG(TLI, *FuncInfo)),
-  SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo)),
+  SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo, fast)),
   GFI(),
   Fast(fast),
   DAGSize(0)
@@ -304,22 +300,21 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
   AA = &getAnalysis<AliasAnalysis>();
 
   TargetMachine &TM = TLI.getTargetMachine();
-  MachineFunction &MF = MachineFunction::construct(&Fn, TM);
-  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  MF = &MachineFunction::construct(&Fn, TM);
   const TargetInstrInfo &TII = *TM.getInstrInfo();
   const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
 
-  if (MF.getFunction()->hasGC())
-    GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
+  if (MF->getFunction()->hasGC())
+    GFI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF->getFunction());
   else
     GFI = 0;
-  RegInfo = &MF.getRegInfo();
+  RegInfo = &MF->getRegInfo();
   DOUT << "\n\n\n=== " << Fn.getName() << "\n";
 
-  FuncInfo->set(Fn, MF, EnableFastISel);
-  MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
-  DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
-  CurDAG->init(MF, MMI, DW);
+  MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+  DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
+  CurDAG->init(*MF, MMI, DW);
+  FuncInfo->set(Fn, *MF, *CurDAG, EnableFastISel);
   SDL->init(GFI, *AA);
 
   for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
@@ -327,17 +322,17 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
       // Mark landing pad.
       FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
 
-  SelectAllBasicBlocks(Fn, MF, MMI, DW, TII);
+  SelectAllBasicBlocks(Fn, *MF, MMI, DW, 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
   // emitting the code for the block.
-  EmitLiveInCopies(MF.begin(), MRI, TRI, TII);
+  EmitLiveInCopies(MF->begin(), *RegInfo, TRI, TII);
 
   // Add function live-ins to entry block live-in set.
   for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(),
          E = RegInfo->livein_end(); I != E; ++I)
-    MF.begin()->addLiveIn(I->first);
+    MF->begin()->addLiveIn(I->first);
 
 #ifndef NDEBUG
   assert(FuncInfo->CatchInfoFound.size() == FuncInfo->CatchInfoLost.size() &&
@@ -365,7 +360,7 @@ static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB,
 /// IsFixedFrameObjectWithPosOffset - Check if object is a fixed frame object and
 /// whether object offset >= 0.
 static bool
-IsFixedFrameObjectWithPosOffset(MachineFrameInfo * MFI, SDValue Op) {
+IsFixedFrameObjectWithPosOffset(MachineFrameInfo *MFI, SDValue Op) {
   if (!isa<FrameIndexSDNode>(Op)) return false;
 
   FrameIndexSDNode * FrameIdxNode = dyn_cast<FrameIndexSDNode>(Op);
@@ -380,7 +375,7 @@ IsFixedFrameObjectWithPosOffset(MachineFrameInfo * MFI, SDValue Op) {
 /// assumes all arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with
 /// virtual registers would be overwritten by direct lowering.
 static bool IsPossiblyOverwrittenArgumentOfTailCall(SDValue Op,
-                                                    MachineFrameInfo * MFI) {
+                                                    MachineFrameInfo *MFI) {
   RegisterSDNode * OpReg = NULL;
   if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
       (Op.getOpcode()== ISD::CopyFromReg &&
@@ -443,9 +438,11 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG,
             MVT VT = Arg.getValueType();
             unsigned VReg = MF.getRegInfo().
               createVirtualRegister(TLI.getRegClassFor(VT));
-            Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag);
+            Chain = DAG.getCopyToReg(Chain, Arg.getDebugLoc(),
+                                     VReg, Arg, InFlag);
             InFlag = Chain.getValue(1);
-            Arg = DAG.getCopyFromReg(Chain, VReg, VT, InFlag);
+            Arg = DAG.getCopyFromReg(Chain, Arg.getDebugLoc(),
+                                     VReg, VT, InFlag);
             Chain = Arg.getValue(1);
             InFlag = Arg.getValue(2);
           }
@@ -622,9 +619,9 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
 
   if (TimePassesIsEnabled) {
     NamedRegionTimer T("DAG Legalization", GroupName);
-    CurDAG->Legalize(DisableLegalizeTypes);
+    CurDAG->Legalize(DisableLegalizeTypes, Fast);
   } else {
-    CurDAG->Legalize(DisableLegalizeTypes);
+    CurDAG->Legalize(DisableLegalizeTypes, Fast);
   }
   
   DOUT << "Legalized selection DAG:\n";
@@ -645,7 +642,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
 
   if (ViewISelDAGs) CurDAG->viewGraph("isel input for " + BlockName);
   
-  if (!Fast && EnableValueProp)
+  if (!Fast)
     ComputeLiveOutVRegInfo();
 
   // Third, instruction select all of the operations to machine code, adding the
@@ -663,12 +660,12 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
   if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName);
 
   // Schedule machine code.
-  ScheduleDAG *Scheduler;
+  ScheduleDAGSDNodes *Scheduler = CreateScheduler();
   if (TimePassesIsEnabled) {
     NamedRegionTimer T("Instruction Scheduling", GroupName);
-    Scheduler = Schedule();
+    Scheduler->Run(CurDAG, BB, BB->end());
   } else {
-    Scheduler = Schedule();
+    Scheduler->Run(CurDAG, BB, BB->end());
   }
 
   if (ViewSUnitDAGs) Scheduler->viewGraph();
@@ -694,14 +691,15 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
   DEBUG(BB->dump());
 }  
 
-void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
+void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
+                                            MachineFunction &MF,
                                             MachineModuleInfo *MMI,
                                             DwarfWriter *DW,
                                             const TargetInstrInfo &TII) {
   // Initialize the Fast-ISel state, if needed.
   FastISel *FastIS = 0;
   if (EnableFastISel)
-    FastIS = TLI.createFastISel(*FuncInfo->MF, MMI, DW,
+    FastIS = TLI.createFastISel(MF, MMI, DW,
                                 FuncInfo->ValueMap,
                                 FuncInfo->MBBMap,
                                 FuncInfo->StaticAllocaMap
@@ -745,7 +743,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
       unsigned LabelID = MMI->addLandingPad(BB);
 
       const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL);
-      BuildMI(BB, II).addImm(LabelID);
+      BuildMI(BB, SDL->getCurDebugLoc(), II).addImm(LabelID);
 
       // Mark exception register as live in.
       unsigned Reg = TLI.getExceptionAddressRegister();
@@ -1064,10 +1062,11 @@ SelectionDAGISel::FinishBasicBlock() {
 }
 
 
-/// Schedule - Pick a safe ordering for instructions for each
-/// target node in the graph.
+/// Create the scheduler. If a specific scheduler was specified
+/// via the SchedulerRegistry, use it, otherwise select the
+/// one preferred by the target.
 ///
-ScheduleDAG *SelectionDAGISel::Schedule() {
+ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
   RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault();
   
   if (!Ctor) {
@@ -1075,16 +1074,11 @@ ScheduleDAG *SelectionDAGISel::Schedule() {
     RegisterScheduler::setDefault(Ctor);
   }
   
-  TargetMachine &TM = getTargetLowering().getTargetMachine();
-  ScheduleDAG *Scheduler = Ctor(this, CurDAG, &TM, BB, Fast);
-  Scheduler->Run();
-
-  return Scheduler;
+  return Ctor(this, Fast);
 }
 
-
-HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
-  return new HazardRecognizer();
+ScheduleHazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
+  return new ScheduleHazardRecognizer();
 }
 
 //===----------------------------------------------------------------------===//
@@ -1174,10 +1168,12 @@ SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops) {
     unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
     if ((Flags & 7) != 4 /*MEM*/) {
       // Just skip over this operand, copying the operands verbatim.
-      Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1);
-      i += (Flags >> 3) + 1;
+      Ops.insert(Ops.end(), InOps.begin()+i,
+                 InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
+      i += InlineAsm::getNumOperandRegisters(Flags) + 1;
     } else {
-      assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
+      assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
+             "Memory operand with multiple values?");
       // Otherwise, this is a memory operand.  Ask the target to select it.
       std::vector<SDValue> SelOps;
       if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) {