diff options
author | Tanya Lattner <tonic@nondot.org> | 2005-04-30 23:07:59 +0000 |
---|---|---|
committer | Tanya Lattner <tonic@nondot.org> | 2005-04-30 23:07:59 +0000 |
commit | c50156360af2e3345b9bf66d2ec2a84b9b55ff9a (patch) | |
tree | dadd0d5802a53880b0e122e4c6d9816e39ee6f61 /lib/Target/SparcV9/ModuloScheduling | |
parent | 50d91d71a51a2370bbe7e727bec180cfadab9cfc (diff) |
Fixed bug in searchPath function for finding nodes between two recurrences.
Changed dependence analyzer to only use dep distances of 2 or less.
This is experimental.
Changed MSchedGraph to be able to represent more then one BB (first steps).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21641 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SparcV9/ModuloScheduling')
5 files changed, 214 insertions, 182 deletions
diff --git a/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp b/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp index 0fd7c604ed..25ad03ad7d 100644 --- a/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp +++ b/lib/Target/SparcV9/ModuloScheduling/DependenceAnalyzer.cpp @@ -218,7 +218,9 @@ void DependenceAnalyzer::advancedDepAnalysis(GetElementPtrInst *gp1, //Find constant index difference int diff = A1->getValue()->getRawValue() - A2->getValue()->getRawValue(); std::cerr << diff << "\n"; - + if(diff > 5) + diff = 2; + if(diff > 0) createDep(deps, valLoad, val2Load, srcBeforeDest, diff); diff --git a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp index 7160f8dc95..cc2edf2f05 100644 --- a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp +++ b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.cpp @@ -153,13 +153,13 @@ MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, std::map<const MachineInstr*, unsigned> &ignoreInstrs, DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm) - : BB(bb), Target(targ) { + : Target(targ) { //Make sure BB is not null, - assert(BB != NULL && "Basic Block is null"); - - //DEBUG(std::cerr << "Constructing graph for " << bb << "\n"); + assert(bb != NULL && "Basic Block is null"); + BBs.push_back(bb); + //Create nodes and edges for this BB buildNodesAndEdges(ignoreInstrs, DA, machineTollvm); @@ -170,7 +170,9 @@ MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, //Copies the graph and keeps a map from old to new nodes MSchedGraph::MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes) - : BB(G.BB), Target(G.Target) { + : Target(G.Target) { + + BBs = G.BBs; std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew; //Copy all nodes @@ -336,179 +338,184 @@ void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ig std::vector<const MachineInstr*> phiInstrs; unsigned index = 0; - //Loop over instructions in MBB and add nodes and edges - for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); - MI != e; ++MI) { - - //Ignore indvar instructions - if(ignoreInstrs.count(MI)) { - ++index; - continue; - } - - //Get each instruction of machine basic block, get the delay - //using the op code, create a new node for it, and add to the - //graph. - - MachineOpCode opCode = MI->getOpcode(); - int delay; + for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(), + BE = BBs.end(); B != BE; ++B) { + + const MachineBasicBlock *BB = *B; + //Loop over instructions in MBB and add nodes and edges + for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); + MI != e; ++MI) { + + //Ignore indvar instructions + if(ignoreInstrs.count(MI)) { + ++index; + continue; + } + + //Get each instruction of machine basic block, get the delay + //using the op code, create a new node for it, and add to the + //graph. + + MachineOpCode opCode = MI->getOpcode(); + int delay; + #if 0 // FIXME: LOOK INTO THIS - //Check if subsequent instructions can be issued before - //the result is ready, if so use min delay. - if(MTI->hasResultInterlock(MIopCode)) - delay = MTI->minLatency(MIopCode); - else + //Check if subsequent instructions can be issued before + //the result is ready, if so use min delay. + if(MTI->hasResultInterlock(MIopCode)) + delay = MTI->minLatency(MIopCode); + else #endif - //Get delay - delay = MTI->maxLatency(opCode); - - //Create new node for this machine instruction and add to the graph. - //Create only if not a nop - if(MTI->isNop(opCode)) - continue; - - //Sparc BE does not use PHI opcode, so assert on this case - assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode"); - - bool isBranch = false; - - //We want to flag the branch node to treat it special - if(MTI->isBranch(opCode)) - isBranch = true; - - //Node is created and added to the graph automatically - MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay, - isBranch); - - DEBUG(std::cerr << "Created Node: " << *node << "\n"); - - //Check OpCode to keep track of memory operations to add memory - //dependencies later. - if(MTI->isLoad(opCode) || MTI->isStore(opCode)) - memInstructions.push_back(node); - - //Loop over all operands, and put them into the register number to - //graph node map for determining dependencies - //If an operands is a use/def, we have an anti dependence to itself - for(unsigned i=0; i < MI->getNumOperands(); ++i) { - //Get Operand - const MachineOperand &mOp = MI->getOperand(i); - - //Check if it has an allocated register - if(mOp.hasAllocatedReg()) { - int regNum = mOp.getReg(); - - if(regNum != SparcV9::g0) { - //Put into our map - regNumtoNodeMap[regNum].push_back(std::make_pair(i, node)); - } + //Get delay + delay = MTI->maxLatency(opCode); + + //Create new node for this machine instruction and add to the graph. + //Create only if not a nop + if(MTI->isNop(opCode)) continue; - } - - - //Add virtual registers dependencies - //Check if any exist in the value map already and create dependencies - //between them. - if(mOp.getType() == MachineOperand::MO_VirtualRegister - || mOp.getType() == MachineOperand::MO_CCRegister) { - - //Make sure virtual register value is not null - assert((mOp.getVRegValue() != NULL) && "Null value is defined"); - - //Check if this is a read operation in a phi node, if so DO NOT PROCESS - if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) { - DEBUG(std::cerr << "Read Operation in a PHI node\n"); + + //Sparc BE does not use PHI opcode, so assert on this case + assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode"); + + bool isBranch = false; + + //We want to flag the branch node to treat it special + if(MTI->isBranch(opCode)) + isBranch = true; + + //Node is created and added to the graph automatically + MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay, + isBranch); + + DEBUG(std::cerr << "Created Node: " << *node << "\n"); + + //Check OpCode to keep track of memory operations to add memory + //dependencies later. + if(MTI->isLoad(opCode) || MTI->isStore(opCode)) + memInstructions.push_back(node); + + //Loop over all operands, and put them into the register number to + //graph node map for determining dependencies + //If an operands is a use/def, we have an anti dependence to itself + for(unsigned i=0; i < MI->getNumOperands(); ++i) { + //Get Operand + const MachineOperand &mOp = MI->getOperand(i); + + //Check if it has an allocated register + if(mOp.hasAllocatedReg()) { + int regNum = mOp.getReg(); + + if(regNum != SparcV9::g0) { + //Put into our map + regNumtoNodeMap[regNum].push_back(std::make_pair(i, node)); + } continue; } - - if (const Value* srcI = mOp.getVRegValue()) { - //Find value in the map - std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V - = valuetoNodeMap.find(srcI); - //If there is something in the map already, add edges from - //those instructions - //to this one we are processing - if(V != valuetoNodeMap.end()) { - addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs); - - //Add to value map - V->second.push_back(std::make_pair(i,node)); + //Add virtual registers dependencies + //Check if any exist in the value map already and create dependencies + //between them. + if(mOp.getType() == MachineOperand::MO_VirtualRegister + || mOp.getType() == MachineOperand::MO_CCRegister) { + + //Make sure virtual register value is not null + assert((mOp.getVRegValue() != NULL) && "Null value is defined"); + + //Check if this is a read operation in a phi node, if so DO NOT PROCESS + if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) { + DEBUG(std::cerr << "Read Operation in a PHI node\n"); + continue; + } + + if (const Value* srcI = mOp.getVRegValue()) { + + //Find value in the map + std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V + = valuetoNodeMap.find(srcI); + + //If there is something in the map already, add edges from + //those instructions + //to this one we are processing + if(V != valuetoNodeMap.end()) { + addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs); + + //Add to value map + V->second.push_back(std::make_pair(i,node)); + } + //Otherwise put it in the map + else + //Put into value map + valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node)); } - //Otherwise put it in the map - else - //Put into value map - valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node)); } } + ++index; } - ++index; - } - - //Loop over LLVM BB, examine phi instructions, and add them to our - //phiInstr list to process - const BasicBlock *llvm_bb = BB->getBasicBlock(); - for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); - I != E; ++I) { - if(const PHINode *PN = dyn_cast<PHINode>(I)) { - MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN); - for (unsigned j = 0; j < tempMvec.size(); j++) { - if(!ignoreInstrs.count(tempMvec[j])) { - DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n"); - phiInstrs.push_back((MachineInstr*) tempMvec[j]); - } - } + + //Loop over LLVM BB, examine phi instructions, and add them to our + //phiInstr list to process + const BasicBlock *llvm_bb = BB->getBasicBlock(); + for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end(); + I != E; ++I) { + if(const PHINode *PN = dyn_cast<PHINode>(I)) { + MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN); + for (unsigned j = 0; j < tempMvec.size(); j++) { + if(!ignoreInstrs.count(tempMvec[j])) { + DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n"); + phiInstrs.push_back((MachineInstr*) tempMvec[j]); + } + } + } + } - - } - - addMemEdges(memInstructions, DA, machineTollvm); - addMachRegEdges(regNumtoNodeMap); - - //Finally deal with PHI Nodes and Value* - for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), - E = phiInstrs.end(); I != E; ++I) { - - //Get Node for this instruction - std::map<const MachineInstr*, MSchedGraphNode*>::iterator X; - X = find(*I); - - if(X == GraphMap.end()) - continue; - - MSchedGraphNode *node = X->second; - - DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n"); - - //Loop over operands for this instruction and add value edges - for(unsigned i=0; i < (*I)->getNumOperands(); ++i) { - //Get Operand - const MachineOperand &mOp = (*I)->getOperand(i); - if((mOp.getType() == MachineOperand::MO_VirtualRegister - || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) { - - //find the value in the map - if (const Value* srcI = mOp.getVRegValue()) { - - //Find value in the map - std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V + + addMemEdges(memInstructions, DA, machineTollvm); + addMachRegEdges(regNumtoNodeMap); + + //Finally deal with PHI Nodes and Value* + for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), + E = phiInstrs.end(); I != E; ++I) { + + //Get Node for this instruction + std::map<const MachineInstr*, MSchedGraphNode*>::iterator X; + X = find(*I); + + if(X == GraphMap.end()) + continue; + + MSchedGraphNode *node = X->second; + + DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n"); + + //Loop over operands for this instruction and add value edges + for(unsigned i=0; i < (*I)->getNumOperands(); ++i) { + //Get Operand + const MachineOperand &mOp = (*I)->getOperand(i); + if((mOp.getType() == MachineOperand::MO_VirtualRegister + || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) { + + //find the value in the map + if (const Value* srcI = mOp.getVRegValue()) { + + //Find value in the map + std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V = valuetoNodeMap.find(srcI); - - //If there is something in the map already, add edges from - //those instructions - //to this one we are processing - if(V != valuetoNodeMap.end()) { - addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), - phiInstrs, 1); + + //If there is something in the map already, add edges from + //those instructions + //to this one we are processing + if(V != valuetoNodeMap.end()) { + addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), + phiInstrs, 1); + } } } } } } } - //Add dependencies for Value*s void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap, MSchedGraphNode *destNode, bool nodeIsUse, diff --git a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h index b0b6e79ed5..6820ca9cbe 100644 --- a/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h +++ b/lib/Target/SparcV9/ModuloScheduling/MSchedGraph.h @@ -233,7 +233,7 @@ namespace llvm { //Graph class to represent dependence graph class MSchedGraph { - const MachineBasicBlock *BB; //Machine basic block + std::vector<const MachineBasicBlock *> BBs; //Machine basic block const TargetMachine &Target; //Target Machine //Nodes @@ -283,7 +283,7 @@ namespace llvm { //Get Target or original machine basic block const TargetMachine* getTarget() { return &Target; } - const MachineBasicBlock* getBB() { return BB; } + std::vector<const MachineBasicBlock*> getBBs() { return BBs; } }; diff --git a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp index e5b8d3c53d..4e57c65aae 100644 --- a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp +++ b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp @@ -1218,7 +1218,8 @@ void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node, void ModuloSchedulingPass::searchPath(MSchedGraphNode *node, std::vector<MSchedGraphNode*> &path, - std::set<MSchedGraphNode*> &nodesToAdd) { + std::set<MSchedGraphNode*> &nodesToAdd, + std::set<MSchedGraphNode*> &new_reccurrence) { //Push node onto the path path.push_back(node); @@ -1227,23 +1228,32 @@ void ModuloSchedulingPass::searchPath(MSchedGraphNode *node, for(MSchedGraphNode::succ_iterator S = node->succ_begin(), SE = node->succ_end(); S != SE; ++S) { - //If this node exists in a recurrence already in the partial order, then add all - //nodes in the path to the set of nodes to add - //Check if its already in our partial order, if not add it to the final vector + //Check if we should ignore this edge first + if(ignoreEdge(node,*S)) + continue; + + //check if successor is in this recurrence, we will get to it eventually + if(new_reccurrence.count(*S)) + continue; + + //If this node exists in a recurrence already in the partial + //order, then add all nodes in the path to the set of nodes to add + //Check if its already in our partial order, if not add it to the + //final vector + bool found = false; for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(), PE = partialOrder.end(); PO != PE; ++PO) { - //Check if we should ignore this edge first - if(ignoreEdge(node,*S)) - continue; - if(PO->count(*S)) { - nodesToAdd.insert(*S); - } - //terminate - else - searchPath(*S, path, nodesToAdd); + found = true; + break; } + } + + if(!found) { + nodesToAdd.insert(*S); + searchPath(*S, path, nodesToAdd, new_reccurrence); + } } //Pop Node off the path @@ -1344,7 +1354,7 @@ void ModuloSchedulingPass::computePartialOrder() { //Add nodes that connect this recurrence to recurrences in the partial path for(std::set<MSchedGraphNode*>::iterator N = new_recurrence.begin(), NE = new_recurrence.end(); N != NE; ++N) - searchPath(*N, path, nodesToAdd); + searchPath(*N, path, nodesToAdd, new_recurrence); //Add nodes to this recurrence if they are not already in the partial order for(std::set<MSchedGraphNode*>::iterator N = nodesToAdd.begin(), NE = nodesToAdd.end(); @@ -1723,8 +1733,10 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr E = FinalNodeOrder.end(); I != E; ++I) { //CalculateEarly and Late start - int EarlyStart = -1; - int LateStart = 99999; //Set to something higher then we would ever expect (FIXME) + bool initialLSVal = false; + bool initialESVal = false; + int EarlyStart = 0; + int LateStart = 0; bool hasSucc = false; bool hasPred = false; bool sched; @@ -1751,7 +1763,12 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II; DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n"); DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n"); - EarlyStart = std::max(EarlyStart, ES_Temp); + if(initialESVal) + EarlyStart = std::max(EarlyStart, ES_Temp); + else { + EarlyStart = ES_Temp; + initialESVal = true; + } hasPred = true; } if((*I)->isSuccessor(*schedNode)) { @@ -1759,7 +1776,12 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr int LS_Temp = nodesByCycle->first - (*I)->getLatency() + diff * II; DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n"); DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n"); - LateStart = std::min(LateStart, LS_Temp); + if(initialLSVal) + LateStart = std::min(LateStart, LS_Temp); + else { + LateStart = LS_Temp; + initialLSVal = true; + } hasSucc = true; } } @@ -1772,7 +1794,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr //Check if this node is a pred or succ to a branch, and restrict its placement //even though the branch is not in the schedule - int count = branches.size(); + /*int count = branches.size(); for(std::vector<MSchedGraphNode*>::iterator B = branches.begin(), BE = branches.end(); B != BE; ++B) { if((*I)->isPredecessor(*B)) { @@ -1794,7 +1816,7 @@ bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB, MSchedGr } count--; - } + }*/ //Check if the node has no pred or successors and set Early Start to its ASAP if(!hasSucc && !hasPred) diff --git a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h index e68948479e..263a6130de 100644 --- a/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h +++ b/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h @@ -113,7 +113,8 @@ namespace llvm { void searchPath(MSchedGraphNode *node, std::vector<MSchedGraphNode*> &path, - std::set<MSchedGraphNode*> &nodesToAdd); + std::set<MSchedGraphNode*> &nodesToAdd, + std::set<MSchedGraphNode*> &new_reccurence); void pathToRecc(MSchedGraphNode *node, std::vector<MSchedGraphNode*> &path, |