diff options
Diffstat (limited to 'lib/CodeGen/InstrSelection/InstrSelection.cpp')
-rw-r--r-- | lib/CodeGen/InstrSelection/InstrSelection.cpp | 156 |
1 files changed, 89 insertions, 67 deletions
diff --git a/lib/CodeGen/InstrSelection/InstrSelection.cpp b/lib/CodeGen/InstrSelection/InstrSelection.cpp index 7153b3cdd1..339ba6474c 100644 --- a/lib/CodeGen/InstrSelection/InstrSelection.cpp +++ b/lib/CodeGen/InstrSelection/InstrSelection.cpp @@ -4,6 +4,10 @@ // InstrSelection.cpp // // Purpose: +// Machine-independent driver file for instruction selection. +// This file constructs a forest of BURG instruction trees and then +// use the BURG-generated tree grammar (BURM) to find the optimal +// instruction sequences for a given machine. // // History: // 7/02/01 - Vikram Adve - Created @@ -35,7 +39,7 @@ cl::Enum<enum SelectDebugLevel_t> SelectDebugLevel("dselect", cl::NoFlags, "enable instruction selection debugging information", clEnumValN(Select_NoDebugInfo, "n", "disable debug output"), clEnumValN(Select_PrintMachineCode, "y", "print generated machine code"), - clEnumValN(Select_DebugInstTrees, "i", "print instruction selection debug info"), + clEnumValN(Select_DebugInstTrees, "i", "print debugging info for instruction selection "), clEnumValN(Select_DebugBurgTrees, "b", "print burg trees"), 0); @@ -45,7 +49,9 @@ cl::Enum<enum SelectDebugLevel_t> SelectDebugLevel("dselect", cl::NoFlags, // Returns true if instruction selection failed, false otherwise. //--------------------------------------------------------------------------- -bool SelectInstructionsForMethod(Method* method, TargetMachine &Target) { +bool +SelectInstructionsForMethod(Method* method, TargetMachine &Target) +{ bool failed = false; // @@ -67,41 +73,47 @@ bool SelectInstructionsForMethod(Method* method, TargetMachine &Target) { const hash_set<InstructionNode*> &treeRoots = instrForest.getRootSet(); for (hash_set<InstructionNode*>::const_iterator treeRootIter = treeRoots.begin(); treeRootIter != treeRoots.end(); - ++treeRootIter) { - InstrTreeNode* basicNode = *treeRootIter; + ++treeRootIter) + { + InstrTreeNode* basicNode = *treeRootIter; - // Invoke BURM to label each tree node with a state - burm_label(basicNode); + // Invoke BURM to label each tree node with a state + burm_label(basicNode); - if (SelectDebugLevel >= Select_DebugBurgTrees) { - printcover(basicNode, 1, 0); - cerr << "\nCover cost == " << treecost(basicNode, 1, 0) << "\n\n"; - printMatches(basicNode); - } + if (SelectDebugLevel >= Select_DebugBurgTrees) + { + printcover(basicNode, 1, 0); + cerr << "\nCover cost == " << treecost(basicNode, 1, 0) << "\n\n"; + printMatches(basicNode); + } - // Then recursively walk the tree to select instructions - if (SelectInstructionsForTree(basicNode, /*goalnt*/1, Target)) { - failed = true; - break; + // Then recursively walk the tree to select instructions + if (SelectInstructionsForTree(basicNode, /*goalnt*/1, Target)) + { + failed = true; + break; + } } - } // // Record instructions in the vector for each basic block // - for (Method::iterator BI = method->begin(); BI != method->end(); ++BI) { - MachineCodeForBasicBlock& bbMvec = (*BI)->getMachineInstrVec(); - for (BasicBlock::iterator II = (*BI)->begin(); II != (*BI)->end(); ++II) { - MachineCodeForVMInstr& mvec = (*II)->getMachineInstrVec(); - for (unsigned i=0; i < mvec.size(); i++) - bbMvec.push_back(mvec[i]); + for (Method::iterator BI = method->begin(); BI != method->end(); ++BI) + { + MachineCodeForBasicBlock& bbMvec = (*BI)->getMachineInstrVec(); + for (BasicBlock::iterator II = (*BI)->begin(); II != (*BI)->end(); ++II) + { + MachineCodeForVMInstr& mvec = (*II)->getMachineInstrVec(); + for (unsigned i=0; i < mvec.size(); i++) + bbMvec.push_back(mvec[i]); + } } - } - if (SelectDebugLevel >= Select_PrintMachineCode) { - cout << endl << "*** Machine instructions after INSTRUCTION SELECTION" << endl; - PrintMachineInstructions(method); - } + if (SelectDebugLevel >= Select_PrintMachineCode) + { + cout << endl << "*** Machine instructions after INSTRUCTION SELECTION" << endl; + PrintMachineInstructions(method); + } return false; } @@ -167,8 +179,10 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode, // may be used by multiple instructions). //--------------------------------------------------------------------------- -bool SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt, - TargetMachine &Target) { +bool +SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt, + TargetMachine &Target) +{ // Use a static vector to avoid allocating a new one per VM instruction static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR]; @@ -176,10 +190,12 @@ bool SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt, // int ruleForNode = burm_rule(treeRoot->state, goalnt); - if (ruleForNode == 0) { - cerr << "Could not match instruction tree for instr selection" << endl; - return true; - } + if (ruleForNode == 0) + { + cerr << "Could not match instruction tree for instr selection" << endl; + assert(0); + return true; + } // Get this rule's non-terminals and the corresponding child nodes (if any) // @@ -190,48 +206,54 @@ bool SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt, // (If this is a list node, not an instruction, then skip this step). // This function is specific to the target architecture. // - if (treeRoot->opLabel != VRegListOp) { - InstructionNode* instrNode = (InstructionNode*)treeRoot; - assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode); + if (treeRoot->opLabel != VRegListOp) + { + InstructionNode* instrNode = (InstructionNode*)treeRoot; + assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode); - unsigned N = GetInstructionsByRule(instrNode, ruleForNode, nts, Target, - minstrVec); - assert(N <= MAX_INSTR_PER_VMINSTR); - for (unsigned i=0; i < N; i++) { - assert(minstrVec[i] != NULL); - instrNode->getInstruction()->addMachineInstruction(minstrVec[i]); + unsigned N = GetInstructionsByRule(instrNode, ruleForNode, nts, Target, + minstrVec); + assert(N <= MAX_INSTR_PER_VMINSTR); + for (unsigned i=0; i < N; i++) + { + assert(minstrVec[i] != NULL); + instrNode->getInstruction()->addMachineInstruction(minstrVec[i]); + } } - } // Then, recursively compile the child nodes, if any. // - if (nts[0]) { // i.e., there is at least one kid - InstrTreeNode* kids[2]; - int currentRule = ruleForNode; - burm_kids(treeRoot, currentRule, kids); - - // First skip over any chain rules so that we don't visit - // the current node again. - // - while (ThisIsAChainRule(currentRule)) { - currentRule = burm_rule(treeRoot->state, nts[0]); - nts = burm_nts[currentRule]; + if (nts[0]) + { // i.e., there is at least one kid + InstrTreeNode* kids[2]; + int currentRule = ruleForNode; burm_kids(treeRoot, currentRule, kids); - } + + // First skip over any chain rules so that we don't visit + // the current node again. + // + while (ThisIsAChainRule(currentRule)) + { + currentRule = burm_rule(treeRoot->state, nts[0]); + nts = burm_nts[currentRule]; + burm_kids(treeRoot, currentRule, kids); + } - // Now we have the first non-chain rule so we have found - // the actual child nodes. Recursively compile them. - // - for (int i = 0; nts[i]; i++) { - assert(i < 2); - InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType(); - if (nodeType == InstrTreeNode::NTVRegListNode || - nodeType == InstrTreeNode::NTInstructionNode) { - if (SelectInstructionsForTree(kids[i], nts[i], Target)) - return true; // failure - } + // Now we have the first non-chain rule so we have found + // the actual child nodes. Recursively compile them. + // + for (int i = 0; nts[i]; i++) + { + assert(i < 2); + InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType(); + if (nodeType == InstrTreeNode::NTVRegListNode || + nodeType == InstrTreeNode::NTInstructionNode) + { + if (SelectInstructionsForTree(kids[i], nts[i], Target)) + return true; // failure + } + } } - } return false; // success } |