Added LLVM project notice to the top of every C++ source file.
[oota-llvm.git] / lib / Target / SparcV9 / InstrSelection / InstrSelection.cpp
index 28bfb74666d87d96eba944b4787a53d481d0ae58..32dc65e6e1e9196e0b558d4984784c789b463bba 100644 (file)
@@ -1,4 +1,11 @@
-//===- InstrSelection.cpp - Machine Independant Inst Selection Driver -----===//
+//===- InstrSelection.cpp - Machine Independent Inst Selection Driver -----===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // Machine-independent driver file for instruction selection.  This file
 // constructs a forest of BURG instruction trees and then uses the
 #include "llvm/CodeGen/InstrSelectionSupport.h"
 #include "llvm/CodeGen/InstrForest.h"
 #include "llvm/CodeGen/MachineCodeForInstruction.h"
-#include "llvm/CodeGen/MachineCodeForBasicBlock.h"
-#include "llvm/CodeGen/MachineCodeForMethod.h"
-#include "llvm/Target/MachineRegInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetRegInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Function.h"
 #include "llvm/iPHINode.h"
 #include "llvm/Pass.h"
 #include "Support/CommandLine.h"
 #include "Support/LeakDetector.h"
-using std::cerr;
 using std::vector;
 
+std::vector<MachineInstr*>
+FixConstantOperandsForInstr(Instruction* vmInstr, MachineInstr* minstr,
+                            TargetMachine& target);
+
 namespace {
   //===--------------------------------------------------------------------===//
   // SelectDebugLevel - Allow command line control over debugging.
@@ -63,18 +72,23 @@ namespace {
                                        int ruleForNode, short* nts);
   public:
     InstructionSelection(TargetMachine &T) : Target(T) {}
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.setPreservesCFG();
+    }
     
     bool runOnFunction(Function &F);
+    virtual const char *getPassName() const { return "Instruction Selection"; }
   };
 }
 
-// Register the pass...
-static RegisterLLC<InstructionSelection>
-X("instselect", "Instruction Selection", createInstructionSelectionPass);
+TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi,
+                               Value *s1, Value *s2, const std::string &name)
+  : Instruction(s1->getType(), Instruction::UserOp1, name)
+{
+  mcfi.addTemp(this);
 
-TmpInstruction::TmpInstruction(Value *s1, Value *s2, const std::string &name)
-  : Instruction(s1->getType(), Instruction::UserOp1, name) {
-  Operands.push_back(Use(s1, this));  // s1 must be nonnull
+  Operands.push_back(Use(s1, this));  // s1 must be non-null
   if (s2) {
     Operands.push_back(Use(s2, this));
   }
@@ -85,9 +99,13 @@ TmpInstruction::TmpInstruction(Value *s1, Value *s2, const std::string &name)
   
 // Constructor that requires the type of the temporary to be specified.
 // Both S1 and S2 may be NULL.(
-TmpInstruction::TmpInstruction(const Type *Ty, Value *s1, Value* s2,
+TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi,
+                               const Type *Ty, Value *s1, Value* s2,
                                const std::string &name)
-  : Instruction(Ty, Instruction::UserOp1, name) {
+  : Instruction(Ty, Instruction::UserOp1, name)
+{
+  mcfi.addTemp(this);
+
   if (s1) { Operands.push_back(Use(s1, this)); }
   if (s2) { Operands.push_back(Use(s2, this)); }
 
@@ -105,10 +123,10 @@ bool InstructionSelection::runOnFunction(Function &F)
   
   if (SelectDebugLevel >= Select_DebugInstTrees)
     {
-      cerr << "\n\n*** Input to instruction selection for function "
-          << F.getName() << "\n\n" << F
-           << "\n\n*** Instruction trees for function "
-          << F.getName() << "\n\n";
+      std::cerr << "\n\n*** Input to instruction selection for function "
+               << F.getName() << "\n\n" << F
+                << "\n\n*** Instruction trees for function "
+                << F.getName() << "\n\n";
       instrForest.dump();
     }
   
@@ -127,7 +145,7 @@ bool InstructionSelection::runOnFunction(Function &F)
       if (SelectDebugLevel >= Select_DebugBurgTrees)
        {
          printcover(basicNode, 1, 0);
-         cerr << "\nCover cost == " << treecost(basicNode, 1, 0) << "\n\n";
+         std::cerr << "\nCover cost == " << treecost(basicNode, 1, 0) <<"\n\n";
          printMatches(basicNode);
        }
       
@@ -136,22 +154,28 @@ bool InstructionSelection::runOnFunction(Function &F)
     }
   
   //
-  // Record instructions in the vector for each basic block
+  // Create the MachineBasicBlock records and add all of the MachineInstrs
+  // defined in the MachineCodeForInstruction objects to also live in the
+  // MachineBasicBlock objects.
   // 
-  for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI)
+  MachineFunction &MF = MachineFunction::get(&F);
+  for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
+    MachineBasicBlock *MCBB = new MachineBasicBlock(BI);
+    MF.getBasicBlockList().push_back(MCBB);
+
     for (BasicBlock::iterator II = BI->begin(); II != BI->end(); ++II) {
       MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(II);
-      MachineCodeForBasicBlock &MCBB = MachineCodeForBasicBlock::get(BI);
-      MCBB.insert(MCBB.end(), mvec.begin(), mvec.end());
+      MCBB->insert(MCBB->end(), mvec.begin(), mvec.end());
     }
+  }
 
   // Insert phi elimination code
   InsertCodeForPhis(F);
   
   if (SelectDebugLevel >= Select_PrintMachineCode)
     {
-      cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n";
-      MachineCodeForMethod::get(&F).dump();
+      std::cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n";
+      MachineFunction::get(&F).dump();
     }
   
   return true;
@@ -167,10 +191,10 @@ InstructionSelection::InsertCodeForPhis(Function &F)
 {
   // for all basic blocks in function
   //
-  for (Function::iterator BB = F.begin(); BB != F.end(); ++BB) {
-    BasicBlock::InstListType &InstList = BB->getInstList();
-    for (BasicBlock::iterator IIt = InstList.begin();
-         PHINode *PN = dyn_cast<PHINode>(&*IIt); ++IIt) {
+  MachineFunction &MF = MachineFunction::get(&F);
+  for (MachineFunction::iterator BB = MF.begin(); BB != MF.end(); ++BB) {
+    for (BasicBlock::const_iterator IIt = BB->getBasicBlock()->begin();
+         const PHINode *PN = dyn_cast<PHINode>(IIt); ++IIt) {
       // FIXME: This is probably wrong...
       Value *PhiCpRes = new PHINode(PN->getType(), "PhiCp:");
 
@@ -189,7 +213,7 @@ InstructionSelection::InsertCodeForPhis(Function &F)
         for (vector<MachineInstr*>::iterator MI=mvec.begin();
              MI != mvec.end(); ++MI) {
           vector<MachineInstr*> CpVec2 =
-            FixConstantOperandsForInstr(PN, *MI, Target);
+            FixConstantOperandsForInstr(const_cast<PHINode*>(PN), *MI, Target);
           CpVec2.push_back(*MI);
           CpVec.insert(CpVec.end(), CpVec2.begin(), CpVec2.end());
         }
@@ -198,12 +222,9 @@ InstructionSelection::InsertCodeForPhis(Function &F)
       }
       
       vector<MachineInstr*> mvec;
-      Target.getRegInfo().cpValue2Value(PhiCpRes, PN, mvec);
-      
-      // get an iterator to machine instructions in the BB
-      MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(BB);
-      
-      bbMvec.insert(bbMvec.begin(), mvec.begin(), mvec.end());
+      Target.getRegInfo().cpValue2Value(PhiCpRes, const_cast<PHINode*>(PN),
+                                        mvec);
+      BB->insert(BB->begin(), mvec.begin(), mvec.end());
     }  // for each Phi Instr in BB
   } // for all BBs in function
 }
@@ -215,26 +236,34 @@ InstructionSelection::InsertCodeForPhis(Function &F)
 
 void
 InstructionSelection::InsertPhiElimInstructions(BasicBlock *BB,
-                                                const vector<MachineInstr*>& CpVec)
+                                            const vector<MachineInstr*>& CpVec)
 { 
   Instruction *TermInst = (Instruction*)BB->getTerminator();
   MachineCodeForInstruction &MC4Term = MachineCodeForInstruction::get(TermInst);
   MachineInstr *FirstMIOfTerm = MC4Term.front();
-  
   assert (FirstMIOfTerm && "No Machine Instrs for terminator");
-  
-  MachineCodeForBasicBlock &bbMvec = MachineCodeForBasicBlock::get(BB);
+
+  MachineFunction &MF = MachineFunction::get(BB->getParent());
+
+  // FIXME: if PHI instructions existed in the machine code, this would be
+  // unnecessary.
+  MachineBasicBlock *MBB = 0;
+  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
+    if (I->getBasicBlock() == BB) {
+      MBB = I;
+      break;
+    }
 
   // find the position of first machine instruction generated by the
   // terminator of this BB
-  MachineCodeForBasicBlock::iterator MCIt =
-    std::find(bbMvec.begin(), bbMvec.end(), FirstMIOfTerm);
+  MachineBasicBlock::iterator MCIt =
+    std::find(MBB->begin(), MBB->end(), FirstMIOfTerm);
 
-  assert( MCIt != bbMvec.end() && "Start inst of terminator not found");
+  assert(MCIt != MBB->end() && "Start inst of terminator not found");
   
   // insert the copy instructions just before the first machine instruction
   // generated for the terminator
-  bbMvec.insert(MCIt, CpVec.begin(), CpVec.end());
+  MBB->insert(MCIt, CpVec.begin(), CpVec.end());
 }
 
 
@@ -263,7 +292,7 @@ InstructionSelection::SelectInstructionsForTree(InstrTreeNode* treeRoot,
   int ruleForNode = burm_rule(treeRoot->state, goalnt);
   
   if (ruleForNode == 0) {
-    cerr << "Could not match instruction tree for instr selection\n";
+    std::cerr << "Could not match instruction tree for instr selection\n";
     abort();
   }
   
@@ -320,7 +349,7 @@ InstructionSelection::SelectInstructionsForTree(InstrTreeNode* treeRoot,
        }
     }
   
-  // Finally, do any postprocessing on this node after its children
+  // Finally, do any post-processing on this node after its children
   // have been translated
   // 
   if (treeRoot->opLabel != VRegListOp)
@@ -359,7 +388,6 @@ InstructionSelection::PostprocessMachineCodeForTree(InstructionNode* instrNode,
 // createInstructionSelectionPass - Public entrypoint for instruction selection
 // and this file as a whole...
 //
-Pass *createInstructionSelectionPass(TargetMachine &T) {
+FunctionPass *createInstructionSelectionPass(TargetMachine &T) {
   return new InstructionSelection(T);
 }
-