| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 1 | //===- InstrSelection.cpp - Machine Independant Inst Selection Driver -----===// | 
|  | 2 | // | 
|  | 3 | // Machine-independent driver file for instruction selection.  This file | 
|  | 4 | // constructs a forest of BURG instruction trees and then uses the | 
|  | 5 | // BURG-generated tree grammar (BURM) to find the optimal instruction sequences | 
|  | 6 | // for a given machine. | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 7 | // | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 9 |  | 
| Chris Lattner | 74d0780 | 2001-09-07 17:15:18 +0000 | [diff] [blame] | 10 | #include "llvm/CodeGen/InstrSelection.h" | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 11 | #include "llvm/CodeGen/InstrSelectionSupport.h" | 
| Chris Lattner | e59929f | 2002-02-03 07:33:46 +0000 | [diff] [blame] | 12 | #include "llvm/CodeGen/InstrForest.h" | 
|  | 13 | #include "llvm/CodeGen/MachineCodeForInstruction.h" | 
| Misha Brukman | 7ae7f84 | 2002-10-28 00:28:31 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/MachineFunction.h" | 
| Chris Lattner | f9781b5 | 2002-12-29 03:13:05 +0000 | [diff] [blame] | 15 | #include "llvm/Target/TargetRegInfo.h" | 
| Chris Lattner | e59929f | 2002-02-03 07:33:46 +0000 | [diff] [blame] | 16 | #include "llvm/Target/TargetMachine.h" | 
| Chris Lattner | 62b7fd1 | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 17 | #include "llvm/Function.h" | 
| Chris Lattner | fb5ae02 | 2001-12-03 18:02:31 +0000 | [diff] [blame] | 18 | #include "llvm/iPHINode.h" | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 19 | #include "llvm/Pass.h" | 
| Chris Lattner | 5de2204 | 2001-11-27 00:03:19 +0000 | [diff] [blame] | 20 | #include "Support/CommandLine.h" | 
| Chris Lattner | 16d4c60 | 2002-09-08 21:08:43 +0000 | [diff] [blame] | 21 | #include "Support/LeakDetector.h" | 
| Anand Shukla | 458496c | 2002-06-25 20:55:50 +0000 | [diff] [blame] | 22 | using std::vector; | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 23 |  | 
| Chris Lattner | 46d4d23 | 2003-01-15 19:47:53 +0000 | [diff] [blame] | 24 | std::vector<MachineInstr*> | 
|  | 25 | FixConstantOperandsForInstr(Instruction* vmInstr, MachineInstr* minstr, | 
|  | 26 | TargetMachine& target); | 
|  | 27 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 28 | namespace { | 
|  | 29 | //===--------------------------------------------------------------------===// | 
|  | 30 | // SelectDebugLevel - Allow command line control over debugging. | 
|  | 31 | // | 
|  | 32 | enum SelectDebugLevel_t { | 
|  | 33 | Select_NoDebugInfo, | 
|  | 34 | Select_PrintMachineCode, | 
|  | 35 | Select_DebugInstTrees, | 
|  | 36 | Select_DebugBurgTrees, | 
|  | 37 | }; | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 38 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 39 | // Enable Debug Options to be specified on the command line | 
|  | 40 | cl::opt<SelectDebugLevel_t> | 
|  | 41 | SelectDebugLevel("dselect", cl::Hidden, | 
|  | 42 | cl::desc("enable instruction selection debug information"), | 
|  | 43 | cl::values( | 
|  | 44 | clEnumValN(Select_NoDebugInfo,      "n", "disable debug output"), | 
|  | 45 | clEnumValN(Select_PrintMachineCode, "y", "print generated machine code"), | 
|  | 46 | clEnumValN(Select_DebugInstTrees,   "i", | 
|  | 47 | "print debugging info for instruction selection"), | 
|  | 48 | clEnumValN(Select_DebugBurgTrees,   "b", "print burg trees"), | 
|  | 49 | 0)); | 
|  | 50 |  | 
|  | 51 |  | 
|  | 52 | //===--------------------------------------------------------------------===// | 
|  | 53 | //  InstructionSelection Pass | 
|  | 54 | // | 
|  | 55 | // This is the actual pass object that drives the instruction selection | 
|  | 56 | // process. | 
|  | 57 | // | 
|  | 58 | class InstructionSelection : public FunctionPass { | 
|  | 59 | TargetMachine &Target; | 
|  | 60 | void InsertCodeForPhis(Function &F); | 
|  | 61 | void InsertPhiElimInstructions(BasicBlock *BB, | 
| Chris Lattner | 3c3457c | 2002-08-09 20:05:34 +0000 | [diff] [blame] | 62 | const vector<MachineInstr*>& CpVec); | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 63 | void SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt); | 
|  | 64 | void PostprocessMachineCodeForTree(InstructionNode* instrNode, | 
|  | 65 | int ruleForNode, short* nts); | 
|  | 66 | public: | 
|  | 67 | InstructionSelection(TargetMachine &T) : Target(T) {} | 
| Chris Lattner | e971441 | 2002-10-23 03:30:47 +0000 | [diff] [blame] | 68 |  | 
|  | 69 | virtual void getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 70 | AU.setPreservesCFG(); | 
|  | 71 | } | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 72 |  | 
|  | 73 | bool runOnFunction(Function &F); | 
| Brian Gaeke | cbd3a40 | 2003-08-14 06:04:49 +0000 | [diff] [blame] | 74 | virtual const char *getPassName() const { return "Instruction Selection"; } | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 75 | }; | 
|  | 76 | } | 
|  | 77 |  | 
| Vikram S. Adve | ad83684 | 2003-05-31 07:41:24 +0000 | [diff] [blame] | 78 | TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, | 
|  | 79 | Value *s1, Value *s2, const std::string &name) | 
|  | 80 | : Instruction(s1->getType(), Instruction::UserOp1, name) | 
|  | 81 | { | 
|  | 82 | mcfi.addTemp(this); | 
|  | 83 |  | 
| Chris Lattner | 16d4c60 | 2002-09-08 21:08:43 +0000 | [diff] [blame] | 84 | Operands.push_back(Use(s1, this));  // s1 must be nonnull | 
|  | 85 | if (s2) { | 
|  | 86 | Operands.push_back(Use(s2, this)); | 
|  | 87 | } | 
|  | 88 |  | 
|  | 89 | // TmpInstructions should not be garbage checked. | 
|  | 90 | LeakDetector::removeGarbageObject(this); | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | // Constructor that requires the type of the temporary to be specified. | 
|  | 94 | // Both S1 and S2 may be NULL.( | 
| Vikram S. Adve | ad83684 | 2003-05-31 07:41:24 +0000 | [diff] [blame] | 95 | TmpInstruction::TmpInstruction(MachineCodeForInstruction& mcfi, | 
|  | 96 | const Type *Ty, Value *s1, Value* s2, | 
| Chris Lattner | 16d4c60 | 2002-09-08 21:08:43 +0000 | [diff] [blame] | 97 | const std::string &name) | 
| Vikram S. Adve | ad83684 | 2003-05-31 07:41:24 +0000 | [diff] [blame] | 98 | : Instruction(Ty, Instruction::UserOp1, name) | 
|  | 99 | { | 
|  | 100 | mcfi.addTemp(this); | 
|  | 101 |  | 
| Chris Lattner | 16d4c60 | 2002-09-08 21:08:43 +0000 | [diff] [blame] | 102 | if (s1) { Operands.push_back(Use(s1, this)); } | 
|  | 103 | if (s2) { Operands.push_back(Use(s2, this)); } | 
|  | 104 |  | 
|  | 105 | // TmpInstructions should not be garbage checked. | 
|  | 106 | LeakDetector::removeGarbageObject(this); | 
|  | 107 | } | 
|  | 108 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 109 |  | 
|  | 110 | bool InstructionSelection::runOnFunction(Function &F) | 
|  | 111 | { | 
| Vikram S. Adve | 8641f9d | 2001-08-28 23:04:38 +0000 | [diff] [blame] | 112 | // | 
|  | 113 | // Build the instruction trees to be given as inputs to BURG. | 
|  | 114 | // | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 115 | InstrForest instrForest(&F); | 
| Vikram S. Adve | 8641f9d | 2001-08-28 23:04:38 +0000 | [diff] [blame] | 116 |  | 
|  | 117 | if (SelectDebugLevel >= Select_DebugInstTrees) | 
|  | 118 | { | 
| Chris Lattner | 46d4d23 | 2003-01-15 19:47:53 +0000 | [diff] [blame] | 119 | std::cerr << "\n\n*** Input to instruction selection for function " | 
|  | 120 | << F.getName() << "\n\n" << F | 
|  | 121 | << "\n\n*** Instruction trees for function " | 
|  | 122 | << F.getName() << "\n\n"; | 
| Vikram S. Adve | 8641f9d | 2001-08-28 23:04:38 +0000 | [diff] [blame] | 123 | instrForest.dump(); | 
|  | 124 | } | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 125 |  | 
|  | 126 | // | 
|  | 127 | // Invoke BURG instruction selection for each tree | 
|  | 128 | // | 
| Vikram S. Adve | 8bc420e | 2002-03-24 03:36:52 +0000 | [diff] [blame] | 129 | for (InstrForest::const_root_iterator RI = instrForest.roots_begin(); | 
|  | 130 | RI != instrForest.roots_end(); ++RI) | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 131 | { | 
| Vikram S. Adve | 8bc420e | 2002-03-24 03:36:52 +0000 | [diff] [blame] | 132 | InstructionNode* basicNode = *RI; | 
|  | 133 | assert(basicNode->parent() == NULL && "A `root' node has a parent?"); | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 134 |  | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 135 | // Invoke BURM to label each tree node with a state | 
|  | 136 | burm_label(basicNode); | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 137 |  | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 138 | if (SelectDebugLevel >= Select_DebugBurgTrees) | 
|  | 139 | { | 
|  | 140 | printcover(basicNode, 1, 0); | 
| Chris Lattner | 46d4d23 | 2003-01-15 19:47:53 +0000 | [diff] [blame] | 141 | std::cerr << "\nCover cost == " << treecost(basicNode, 1, 0) <<"\n\n"; | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 142 | printMatches(basicNode); | 
|  | 143 | } | 
|  | 144 |  | 
|  | 145 | // Then recursively walk the tree to select instructions | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 146 | SelectInstructionsForTree(basicNode, /*goalnt*/1); | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 147 | } | 
|  | 148 |  | 
| Vikram S. Adve | da0c7d8 | 2001-07-30 18:48:43 +0000 | [diff] [blame] | 149 | // | 
| Chris Lattner | 8c63b68 | 2002-10-28 05:30:46 +0000 | [diff] [blame] | 150 | // Create the MachineBasicBlock records and add all of the MachineInstrs | 
|  | 151 | // defined in the MachineCodeForInstruction objects to also live in the | 
|  | 152 | // MachineBasicBlock objects. | 
| Vikram S. Adve | da0c7d8 | 2001-07-30 18:48:43 +0000 | [diff] [blame] | 153 | // | 
| Chris Lattner | 8c63b68 | 2002-10-28 05:30:46 +0000 | [diff] [blame] | 154 | MachineFunction &MF = MachineFunction::get(&F); | 
|  | 155 | for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { | 
|  | 156 | MachineBasicBlock *MCBB = new MachineBasicBlock(BI); | 
|  | 157 | MF.getBasicBlockList().push_back(MCBB); | 
|  | 158 |  | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 159 | for (BasicBlock::iterator II = BI->begin(); II != BI->end(); ++II) { | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 160 | MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(II); | 
| Chris Lattner | 8c63b68 | 2002-10-28 05:30:46 +0000 | [diff] [blame] | 161 | MCBB->insert(MCBB->end(), mvec.begin(), mvec.end()); | 
| Vikram S. Adve | da0c7d8 | 2001-07-30 18:48:43 +0000 | [diff] [blame] | 162 | } | 
| Chris Lattner | 8c63b68 | 2002-10-28 05:30:46 +0000 | [diff] [blame] | 163 | } | 
| Ruchira Sasanka | 9f246e6 | 2001-11-12 14:44:50 +0000 | [diff] [blame] | 164 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 165 | // Insert phi elimination code | 
|  | 166 | InsertCodeForPhis(F); | 
| Vikram S. Adve | da0c7d8 | 2001-07-30 18:48:43 +0000 | [diff] [blame] | 167 |  | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 168 | if (SelectDebugLevel >= Select_PrintMachineCode) | 
|  | 169 | { | 
| Chris Lattner | 46d4d23 | 2003-01-15 19:47:53 +0000 | [diff] [blame] | 170 | std::cerr << "\n*** Machine instructions after INSTRUCTION SELECTION\n"; | 
| Misha Brukman | 7ae7f84 | 2002-10-28 00:28:31 +0000 | [diff] [blame] | 171 | MachineFunction::get(&F).dump(); | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 172 | } | 
| Vikram S. Adve | 8641f9d | 2001-08-28 23:04:38 +0000 | [diff] [blame] | 173 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 174 | return true; | 
| Ruchira Sasanka | 9f246e6 | 2001-11-12 14:44:50 +0000 | [diff] [blame] | 175 | } | 
|  | 176 |  | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 177 |  | 
|  | 178 | //------------------------------------------------------------------------- | 
|  | 179 | // This method inserts phi elimination code for all BBs in a method | 
|  | 180 | //------------------------------------------------------------------------- | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 181 |  | 
| Vikram S. Adve | d2c71c1d | 2002-03-18 03:31:54 +0000 | [diff] [blame] | 182 | void | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 183 | InstructionSelection::InsertCodeForPhis(Function &F) | 
| Vikram S. Adve | d2c71c1d | 2002-03-18 03:31:54 +0000 | [diff] [blame] | 184 | { | 
| Chris Lattner | 62b7fd1 | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 185 | // for all basic blocks in function | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 186 | // | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 187 | MachineFunction &MF = MachineFunction::get(&F); | 
|  | 188 | for (MachineFunction::iterator BB = MF.begin(); BB != MF.end(); ++BB) { | 
| Chris Lattner | 0c8de4b | 2003-07-26 23:29:51 +0000 | [diff] [blame] | 189 | for (BasicBlock::const_iterator IIt = BB->getBasicBlock()->begin(); | 
|  | 190 | const PHINode *PN = dyn_cast<PHINode>(IIt); ++IIt) { | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 191 | // FIXME: This is probably wrong... | 
|  | 192 | Value *PhiCpRes = new PHINode(PN->getType(), "PhiCp:"); | 
| Chris Lattner | 7494650 | 2002-09-08 21:19:29 +0000 | [diff] [blame] | 193 |  | 
|  | 194 | // The leak detector shouldn't track these nodes.  They are not garbage, | 
|  | 195 | // even though their parent field is never filled in. | 
|  | 196 | // | 
|  | 197 | LeakDetector::removeGarbageObject(PhiCpRes); | 
|  | 198 |  | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 199 | // for each incoming value of the phi, insert phi elimination | 
|  | 200 | // | 
|  | 201 | for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) { | 
|  | 202 | // insert the copy instruction to the predecessor BB | 
|  | 203 | vector<MachineInstr*> mvec, CpVec; | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 204 | Target.getRegInfo().cpValue2Value(PN->getIncomingValue(i), PhiCpRes, | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 205 | mvec); | 
|  | 206 | for (vector<MachineInstr*>::iterator MI=mvec.begin(); | 
|  | 207 | MI != mvec.end(); ++MI) { | 
|  | 208 | vector<MachineInstr*> CpVec2 = | 
| Chris Lattner | 0c8de4b | 2003-07-26 23:29:51 +0000 | [diff] [blame] | 209 | FixConstantOperandsForInstr(const_cast<PHINode*>(PN), *MI, Target); | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 210 | CpVec2.push_back(*MI); | 
|  | 211 | CpVec.insert(CpVec.end(), CpVec2.begin(), CpVec2.end()); | 
|  | 212 | } | 
| Vikram S. Adve | d2c71c1d | 2002-03-18 03:31:54 +0000 | [diff] [blame] | 213 |  | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 214 | InsertPhiElimInstructions(PN->getIncomingBlock(i), CpVec); | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 215 | } | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 216 |  | 
| Chris Lattner | 7076ff2 | 2002-06-25 16:13:21 +0000 | [diff] [blame] | 217 | vector<MachineInstr*> mvec; | 
| Chris Lattner | 0c8de4b | 2003-07-26 23:29:51 +0000 | [diff] [blame] | 218 | Target.getRegInfo().cpValue2Value(PhiCpRes, const_cast<PHINode*>(PN), | 
|  | 219 | mvec); | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 220 | BB->insert(BB->begin(), mvec.begin(), mvec.end()); | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 221 | }  // for each Phi Instr in BB | 
| Chris Lattner | 62b7fd1 | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 222 | } // for all BBs in function | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 223 | } | 
|  | 224 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 225 | //------------------------------------------------------------------------- | 
|  | 226 | // Thid method inserts a copy instruction to a predecessor BB as a result | 
|  | 227 | // of phi elimination. | 
|  | 228 | //------------------------------------------------------------------------- | 
| Ruchira Sasanka | c5989f6 | 2001-11-15 00:27:14 +0000 | [diff] [blame] | 229 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 230 | void | 
|  | 231 | InstructionSelection::InsertPhiElimInstructions(BasicBlock *BB, | 
| Chris Lattner | a2620ac | 2002-11-09 00:49:43 +0000 | [diff] [blame] | 232 | const vector<MachineInstr*>& CpVec) | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 233 | { | 
|  | 234 | Instruction *TermInst = (Instruction*)BB->getTerminator(); | 
|  | 235 | MachineCodeForInstruction &MC4Term = MachineCodeForInstruction::get(TermInst); | 
|  | 236 | MachineInstr *FirstMIOfTerm = MC4Term.front(); | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 237 | assert (FirstMIOfTerm && "No Machine Instrs for terminator"); | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 238 |  | 
|  | 239 | MachineFunction &MF = MachineFunction::get(BB->getParent()); | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 240 |  | 
|  | 241 | // FIXME: if PHI instructions existed in the machine code, this would be | 
|  | 242 | // unnecesary. | 
| Chris Lattner | a2620ac | 2002-11-09 00:49:43 +0000 | [diff] [blame] | 243 | MachineBasicBlock *MBB = 0; | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 244 | for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) | 
|  | 245 | if (I->getBasicBlock() == BB) { | 
|  | 246 | MBB = I; | 
|  | 247 | break; | 
|  | 248 | } | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 249 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 250 | // find the position of first machine instruction generated by the | 
|  | 251 | // terminator of this BB | 
| Chris Lattner | 8710aab | 2002-10-28 01:41:47 +0000 | [diff] [blame] | 252 | MachineBasicBlock::iterator MCIt = | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 253 | std::find(MBB->begin(), MBB->end(), FirstMIOfTerm); | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 254 |  | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 255 | assert(MCIt != MBB->end() && "Start inst of terminator not found"); | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 256 |  | 
|  | 257 | // insert the copy instructions just before the first machine instruction | 
|  | 258 | // generated for the terminator | 
| Chris Lattner | 76d5927 | 2002-10-28 19:01:16 +0000 | [diff] [blame] | 259 | MBB->insert(MCIt, CpVec.begin(), CpVec.end()); | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 260 | } | 
|  | 261 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 262 |  | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 263 | //--------------------------------------------------------------------------- | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 264 | // Function SelectInstructionsForTree | 
|  | 265 | // | 
|  | 266 | // Recursively walk the tree to select instructions. | 
|  | 267 | // Do this top-down so that child instructions can exploit decisions | 
|  | 268 | // made at the child instructions. | 
|  | 269 | // | 
|  | 270 | // E.g., if br(setle(reg,const)) decides the constant is 0 and uses | 
|  | 271 | // a branch-on-integer-register instruction, then the setle node | 
|  | 272 | // can use that information to avoid generating the SUBcc instruction. | 
|  | 273 | // | 
|  | 274 | // Note that this cannot be done bottom-up because setle must do this | 
|  | 275 | // only if it is a child of the branch (otherwise, the result of setle | 
|  | 276 | // may be used by multiple instructions). | 
|  | 277 | //--------------------------------------------------------------------------- | 
|  | 278 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 279 | void | 
|  | 280 | InstructionSelection::SelectInstructionsForTree(InstrTreeNode* treeRoot, | 
|  | 281 | int goalnt) | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 282 | { | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 283 | // Get the rule that matches this node. | 
|  | 284 | // | 
|  | 285 | int ruleForNode = burm_rule(treeRoot->state, goalnt); | 
|  | 286 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 287 | if (ruleForNode == 0) { | 
| Chris Lattner | 46d4d23 | 2003-01-15 19:47:53 +0000 | [diff] [blame] | 288 | std::cerr << "Could not match instruction tree for instr selection\n"; | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 289 | abort(); | 
|  | 290 | } | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 291 |  | 
|  | 292 | // Get this rule's non-terminals and the corresponding child nodes (if any) | 
|  | 293 | // | 
|  | 294 | short *nts = burm_nts[ruleForNode]; | 
|  | 295 |  | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 296 | // First, select instructions for the current node and rule. | 
|  | 297 | // (If this is a list node, not an instruction, then skip this step). | 
|  | 298 | // This function is specific to the target architecture. | 
|  | 299 | // | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 300 | if (treeRoot->opLabel != VRegListOp) | 
|  | 301 | { | 
| Chris Lattner | 3c3457c | 2002-08-09 20:05:34 +0000 | [diff] [blame] | 302 | vector<MachineInstr*> minstrVec; | 
| Vikram S. Adve | d2c71c1d | 2002-03-18 03:31:54 +0000 | [diff] [blame] | 303 |  | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 304 | InstructionNode* instrNode = (InstructionNode*)treeRoot; | 
|  | 305 | assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode); | 
| Vikram S. Adve | 3686293 | 2001-10-22 13:51:09 +0000 | [diff] [blame] | 306 |  | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 307 | GetInstructionsByRule(instrNode, ruleForNode, nts, Target, minstrVec); | 
| Vikram S. Adve | d2c71c1d | 2002-03-18 03:31:54 +0000 | [diff] [blame] | 308 |  | 
| Chris Lattner | e59929f | 2002-02-03 07:33:46 +0000 | [diff] [blame] | 309 | MachineCodeForInstruction &mvec = | 
|  | 310 | MachineCodeForInstruction::get(instrNode->getInstruction()); | 
| Vikram S. Adve | d2c71c1d | 2002-03-18 03:31:54 +0000 | [diff] [blame] | 311 | mvec.insert(mvec.end(), minstrVec.begin(), minstrVec.end()); | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 312 | } | 
|  | 313 |  | 
|  | 314 | // Then, recursively compile the child nodes, if any. | 
|  | 315 | // | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 316 | if (nts[0]) | 
|  | 317 | { // i.e., there is at least one kid | 
|  | 318 | InstrTreeNode* kids[2]; | 
|  | 319 | int currentRule = ruleForNode; | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 320 | burm_kids(treeRoot, currentRule, kids); | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 321 |  | 
|  | 322 | // First skip over any chain rules so that we don't visit | 
|  | 323 | // the current node again. | 
|  | 324 | // | 
|  | 325 | while (ThisIsAChainRule(currentRule)) | 
|  | 326 | { | 
|  | 327 | currentRule = burm_rule(treeRoot->state, nts[0]); | 
|  | 328 | nts = burm_nts[currentRule]; | 
|  | 329 | burm_kids(treeRoot, currentRule, kids); | 
|  | 330 | } | 
| Chris Lattner | 0a823a0 | 2001-09-14 03:37:52 +0000 | [diff] [blame] | 331 |  | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 332 | // Now we have the first non-chain rule so we have found | 
|  | 333 | // the actual child nodes.  Recursively compile them. | 
|  | 334 | // | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 335 | for (unsigned i = 0; nts[i]; i++) | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 336 | { | 
|  | 337 | assert(i < 2); | 
|  | 338 | InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType(); | 
|  | 339 | if (nodeType == InstrTreeNode::NTVRegListNode || | 
|  | 340 | nodeType == InstrTreeNode::NTInstructionNode) | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 341 | SelectInstructionsForTree(kids[i], nts[i]); | 
| Vikram S. Adve | bb81dae | 2001-09-18 12:56:28 +0000 | [diff] [blame] | 342 | } | 
| Chris Lattner | 0a823a0 | 2001-09-14 03:37:52 +0000 | [diff] [blame] | 343 | } | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 344 |  | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 345 | // Finally, do any postprocessing on this node after its children | 
|  | 346 | // have been translated | 
|  | 347 | // | 
|  | 348 | if (treeRoot->opLabel != VRegListOp) | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 349 | PostprocessMachineCodeForTree((InstructionNode*)treeRoot, ruleForNode, nts); | 
|  | 350 | } | 
|  | 351 |  | 
|  | 352 | //--------------------------------------------------------------------------- | 
|  | 353 | // Function PostprocessMachineCodeForTree | 
|  | 354 | // | 
|  | 355 | // Apply any final cleanups to machine code for the root of a subtree | 
|  | 356 | // after selection for all its children has been completed. | 
|  | 357 | // | 
|  | 358 | void | 
|  | 359 | InstructionSelection::PostprocessMachineCodeForTree(InstructionNode* instrNode, | 
|  | 360 | int ruleForNode, | 
|  | 361 | short* nts) | 
|  | 362 | { | 
|  | 363 | // Fix up any constant operands in the machine instructions to either | 
|  | 364 | // use an immediate field or to load the constant into a register | 
|  | 365 | // Walk backwards and use direct indexes to allow insertion before current | 
|  | 366 | // | 
|  | 367 | Instruction* vmInstr = instrNode->getInstruction(); | 
|  | 368 | MachineCodeForInstruction &mvec = MachineCodeForInstruction::get(vmInstr); | 
| Chris Lattner | 3c3457c | 2002-08-09 20:05:34 +0000 | [diff] [blame] | 369 | for (unsigned i = mvec.size(); i != 0; --i) | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 370 | { | 
| Chris Lattner | 3c3457c | 2002-08-09 20:05:34 +0000 | [diff] [blame] | 371 | vector<MachineInstr*> loadConstVec = | 
|  | 372 | FixConstantOperandsForInstr(vmInstr, mvec[i-1], Target); | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 373 |  | 
| Chris Lattner | 3c3457c | 2002-08-09 20:05:34 +0000 | [diff] [blame] | 374 | mvec.insert(mvec.begin()+i-1, loadConstVec.begin(), loadConstVec.end()); | 
| Vikram S. Adve | 6d19dc9 | 2001-10-17 23:57:50 +0000 | [diff] [blame] | 375 | } | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 376 | } | 
|  | 377 |  | 
|  | 378 |  | 
|  | 379 |  | 
|  | 380 | //===----------------------------------------------------------------------===// | 
|  | 381 | // createInstructionSelectionPass - Public entrypoint for instruction selection | 
|  | 382 | // and this file as a whole... | 
|  | 383 | // | 
| Brian Gaeke | cbd3a40 | 2003-08-14 06:04:49 +0000 | [diff] [blame] | 384 | FunctionPass *createInstructionSelectionPass(TargetMachine &T) { | 
| Chris Lattner | 4bc962d | 2002-07-30 03:57:36 +0000 | [diff] [blame] | 385 | return new InstructionSelection(T); | 
| Vikram S. Adve | ab9e557 | 2001-07-21 12:41:50 +0000 | [diff] [blame] | 386 | } |