blob: 5441d3cec47c7857b39010c307986a65f3072d42 [file] [log] [blame]
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001//===-- ModuloScheduling.cpp - ModuloScheduling ----------------*- C++ -*-===//
2//
John Criswellb576c942003-10-20 19:43:21 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Tanya Lattnerd14b8372004-03-01 02:50:01 +00007//
John Criswellb576c942003-10-20 19:43:21 +00008//===----------------------------------------------------------------------===//
Tanya Lattnerd14b8372004-03-01 02:50:01 +00009//
Tanya Lattner0a88d2d2004-07-30 23:36:10 +000010// This ModuloScheduling pass is based on the Swing Modulo Scheduling
11// algorithm.
Misha Brukman82fd8d82004-08-02 13:59:10 +000012//
Guochun Shif1c154f2003-03-27 17:57:44 +000013//===----------------------------------------------------------------------===//
14
Tanya Lattnerd14b8372004-03-01 02:50:01 +000015#define DEBUG_TYPE "ModuloSched"
16
17#include "ModuloScheduling.h"
Tanya Lattner9532ab92005-03-23 01:47:20 +000018#include "llvm/Constants.h"
Tanya Lattner0a88d2d2004-07-30 23:36:10 +000019#include "llvm/Instructions.h"
20#include "llvm/Function.h"
Tanya Lattnerd14b8372004-03-01 02:50:01 +000021#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/Passes.h"
23#include "llvm/Support/CFG.h"
24#include "llvm/Target/TargetSchedInfo.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000025#include "llvm/Support/Debug.h"
26#include "llvm/Support/GraphWriter.h"
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000027#include "llvm/ADT/SCCIterator.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000028#include "llvm/ADT/StringExtras.h"
Tanya Lattnere1df2122004-11-22 20:41:24 +000029#include "llvm/ADT/Statistic.h"
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000030#include "llvm/Support/Timer.h"
Misha Brukman82fd8d82004-08-02 13:59:10 +000031#include <cmath>
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +000032#include <algorithm>
Tanya Lattnerd14b8372004-03-01 02:50:01 +000033#include <fstream>
34#include <sstream>
Misha Brukman82fd8d82004-08-02 13:59:10 +000035#include <utility>
36#include <vector>
Misha Brukman7da1e6e2004-10-10 23:34:50 +000037#include "../MachineCodeForInstruction.h"
38#include "../SparcV9TmpInstr.h"
39#include "../SparcV9Internals.h"
40#include "../SparcV9RegisterInfo.h"
Tanya Lattnerd14b8372004-03-01 02:50:01 +000041using namespace llvm;
42
43/// Create ModuloSchedulingPass
44///
45FunctionPass *llvm::createModuloSchedulingPass(TargetMachine & targ) {
46 DEBUG(std::cerr << "Created ModuloSchedulingPass\n");
47 return new ModuloSchedulingPass(targ);
48}
49
Tanya Lattner0a88d2d2004-07-30 23:36:10 +000050
51//Graph Traits for printing out the dependence graph
Tanya Lattnerd14b8372004-03-01 02:50:01 +000052template<typename GraphType>
53static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
54 const GraphType &GT) {
55 std::string Filename = GraphName + ".dot";
56 O << "Writing '" << Filename << "'...";
57 std::ofstream F(Filename.c_str());
58
59 if (F.good())
60 WriteGraph(F, GT);
61 else
62 O << " error opening file for writing!";
63 O << "\n";
64};
Guochun Shif1c154f2003-03-27 17:57:44 +000065
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000066
67#if 1
68#define TIME_REGION(VARNAME, DESC) \
69 NamedRegionTimer VARNAME(DESC)
70#else
71#define TIME_REGION(VARNAME, DESC)
72#endif
73
74
Tanya Lattner0a88d2d2004-07-30 23:36:10 +000075//Graph Traits for printing out the dependence graph
Brian Gaeked0fde302003-11-11 22:41:34 +000076namespace llvm {
Tanya Lattnere1df2122004-11-22 20:41:24 +000077 Statistic<> ValidLoops("modulosched-validLoops", "Number of candidate loops modulo-scheduled");
78 Statistic<> MSLoops("modulosched-schedLoops", "Number of loops successfully modulo-scheduled");
79 Statistic<> IncreasedII("modulosched-increasedII", "Number of times we had to increase II");
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000080 Statistic<> SingleBBLoops("modulosched-singeBBLoops", "Number of single basic block loops");
Tanya Lattnerdb1680b2005-02-16 04:00:59 +000081 Statistic<> NoSched("modulosched-noSched", "No schedule");
82 Statistic<> SameStage("modulosched-sameStage", "Max stage is 0");
Brian Gaeked0fde302003-11-11 22:41:34 +000083
Tanya Lattnerd14b8372004-03-01 02:50:01 +000084 template<>
85 struct DOTGraphTraits<MSchedGraph*> : public DefaultDOTGraphTraits {
86 static std::string getGraphName(MSchedGraph *F) {
87 return "Dependence Graph";
88 }
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000089
Tanya Lattnerd14b8372004-03-01 02:50:01 +000090 static std::string getNodeLabel(MSchedGraphNode *Node, MSchedGraph *Graph) {
91 if (Node->getInst()) {
92 std::stringstream ss;
93 ss << *(Node->getInst());
94 return ss.str(); //((MachineInstr*)Node->getInst());
95 }
96 else
97 return "No Inst";
98 }
99 static std::string getEdgeSourceLabel(MSchedGraphNode *Node,
100 MSchedGraphNode::succ_iterator I) {
101 //Label each edge with the type of dependence
102 std::string edgelabel = "";
103 switch (I.getEdge().getDepOrderType()) {
104
105 case MSchedGraphEdge::TrueDep:
106 edgelabel = "True";
107 break;
108
109 case MSchedGraphEdge::AntiDep:
110 edgelabel = "Anti";
111 break;
112
113 case MSchedGraphEdge::OutputDep:
114 edgelabel = "Output";
115 break;
116
117 default:
118 edgelabel = "Unknown";
119 break;
120 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000121
122 //FIXME
123 int iteDiff = I.getEdge().getIteDiff();
124 std::string intStr = "(IteDiff: ";
125 intStr += itostr(iteDiff);
126
127 intStr += ")";
128 edgelabel += intStr;
129
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000130 return edgelabel;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000131 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000132 };
Guochun Shif1c154f2003-03-27 17:57:44 +0000133}
Tanya Lattner4f839cc2003-08-28 17:12:14 +0000134
Tanya Lattner9532ab92005-03-23 01:47:20 +0000135
136#include <unistd.h>
137
Misha Brukmanaa41c3c2003-10-10 17:41:32 +0000138/// ModuloScheduling::runOnFunction - main transformation entry point
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000139/// The Swing Modulo Schedule algorithm has three basic steps:
140/// 1) Computation and Analysis of the dependence graph
141/// 2) Ordering of the nodes
142/// 3) Scheduling
143///
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000144bool ModuloSchedulingPass::runOnFunction(Function &F) {
Tanya Lattner9532ab92005-03-23 01:47:20 +0000145 alarm(300);
146
Tanya Lattner4f839cc2003-08-28 17:12:14 +0000147 bool Changed = false;
Tanya Lattnerced82222004-11-16 21:31:37 +0000148 int numMS = 0;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000149
Tanya Lattner420025b2004-10-10 22:44:35 +0000150 DEBUG(std::cerr << "Creating ModuloSchedGraph for each valid BasicBlock in " + F.getName() + "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000151
152 //Get MachineFunction
153 MachineFunction &MF = MachineFunction::get(&F);
Tanya Lattner260652a2004-10-30 00:39:07 +0000154
Tanya Lattner9532ab92005-03-23 01:47:20 +0000155 AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
156 TargetData &TD = getAnalysis<TargetData>();
157
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000158 //Worklist
159 std::vector<MachineBasicBlock*> Worklist;
160
161 //Iterate over BasicBlocks and put them into our worklist if they are valid
162 for (MachineFunction::iterator BI = MF.begin(); BI != MF.end(); ++BI)
Tanya Lattnere1df2122004-11-22 20:41:24 +0000163 if(MachineBBisValid(BI)) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000164 Worklist.push_back(&*BI);
Tanya Lattnere1df2122004-11-22 20:41:24 +0000165 ++ValidLoops;
166 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000167
Tanya Lattner80f08552004-11-02 21:04:56 +0000168 defaultInst = 0;
169
Tanya Lattner420025b2004-10-10 22:44:35 +0000170 DEBUG(if(Worklist.size() == 0) std::cerr << "No single basic block loops in function to ModuloSchedule\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000171
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000172 //Iterate over the worklist and perform scheduling
173 for(std::vector<MachineBasicBlock*>::iterator BI = Worklist.begin(),
174 BE = Worklist.end(); BI != BE; ++BI) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000175
176 //Print out BB for debugging
177 DEBUG(std::cerr << "ModuloScheduling BB: \n"; (*BI)->print(std::cerr));
178
Tanya Lattner9532ab92005-03-23 01:47:20 +0000179 //Print out LLVM BB
180 DEBUG(std::cerr << "ModuloScheduling LLVMBB: \n"; (*BI)->getBasicBlock()->print(std::cerr));
181
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000182 //Catch the odd case where we only have TmpInstructions and no real Value*s
183 if(!CreateDefMap(*BI)) {
184 //Clear out our maps for the next basic block that is processed
185 nodeToAttributesMap.clear();
186 partialOrder.clear();
187 recurrenceList.clear();
188 FinalNodeOrder.clear();
189 schedule.clear();
190 defMap.clear();
191 continue;
192 }
Tanya Lattnerced82222004-11-16 21:31:37 +0000193
Tanya Lattner9532ab92005-03-23 01:47:20 +0000194 MSchedGraph *MSG = new MSchedGraph(*BI, target, AA, TD, indVarInstrs[*BI]);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000195
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000196 //Write Graph out to file
197 DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG));
198
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000199 //Calculate Resource II
200 int ResMII = calculateResMII(*BI);
201
202 //Calculate Recurrence II
203 int RecMII = calculateRecMII(MSG, ResMII);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000204
205 DEBUG(std::cerr << "Number of reccurrences found: " << recurrenceList.size() << "\n");
206
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000207
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000208
209
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000210 //Our starting initiation interval is the maximum of RecMII and ResMII
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000211 II = std::max(RecMII, ResMII);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000212
213 //Print out II, RecMII, and ResMII
Tanya Lattner260652a2004-10-30 00:39:07 +0000214 DEBUG(std::cerr << "II starts out as " << II << " ( RecMII=" << RecMII << " and ResMII=" << ResMII << ")\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000215
Tanya Lattner260652a2004-10-30 00:39:07 +0000216 //Dump node properties if in debug mode
217 DEBUG(for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
218 E = nodeToAttributesMap.end(); I !=E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000219 std::cerr << "Node: " << *(I->first) << " ASAP: " << I->second.ASAP << " ALAP: "
220 << I->second.ALAP << " MOB: " << I->second.MOB << " Depth: " << I->second.depth
221 << " Height: " << I->second.height << "\n";
222 });
Tanya Lattner260652a2004-10-30 00:39:07 +0000223
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000224 //Calculate Node Properties
225 calculateNodeAttributes(MSG, ResMII);
226
227 //Dump node properties if in debug mode
228 DEBUG(for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
229 E = nodeToAttributesMap.end(); I !=E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000230 std::cerr << "Node: " << *(I->first) << " ASAP: " << I->second.ASAP << " ALAP: "
231 << I->second.ALAP << " MOB: " << I->second.MOB << " Depth: " << I->second.depth
232 << " Height: " << I->second.height << "\n";
233 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000234
235 //Put nodes in order to schedule them
236 computePartialOrder();
237
238 //Dump out partial order
Tanya Lattner260652a2004-10-30 00:39:07 +0000239 DEBUG(for(std::vector<std::set<MSchedGraphNode*> >::iterator I = partialOrder.begin(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000240 E = partialOrder.end(); I !=E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000241 std::cerr << "Start set in PO\n";
242 for(std::set<MSchedGraphNode*>::iterator J = I->begin(), JE = I->end(); J != JE; ++J)
243 std::cerr << "PO:" << **J << "\n";
244 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000245
246 //Place nodes in final order
247 orderNodes();
248
249 //Dump out order of nodes
250 DEBUG(for(std::vector<MSchedGraphNode*>::iterator I = FinalNodeOrder.begin(), E = FinalNodeOrder.end(); I != E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000251 std::cerr << "FO:" << **I << "\n";
252 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000253
254 //Finally schedule nodes
Tanya Lattner9532ab92005-03-23 01:47:20 +0000255 bool haveSched = computeSchedule(*BI);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000256
257 //Print out final schedule
258 DEBUG(schedule.print(std::cerr));
259
Tanya Lattner260652a2004-10-30 00:39:07 +0000260 //Final scheduling step is to reconstruct the loop only if we actual have
261 //stage > 0
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000262 if(schedule.getMaxStage() != 0 && haveSched) {
Tanya Lattner260652a2004-10-30 00:39:07 +0000263 reconstructLoop(*BI);
Tanya Lattnere1df2122004-11-22 20:41:24 +0000264 ++MSLoops;
Tanya Lattnerced82222004-11-16 21:31:37 +0000265 Changed = true;
266 }
Tanya Lattnerdb1680b2005-02-16 04:00:59 +0000267 else {
268 if(!haveSched)
269 ++NoSched;
270 else
271 ++SameStage;
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000272 DEBUG(std::cerr << "Max stage is 0, so no change in loop or reached cap\n");
Tanya Lattnerdb1680b2005-02-16 04:00:59 +0000273 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000274 //Clear out our maps for the next basic block that is processed
275 nodeToAttributesMap.clear();
276 partialOrder.clear();
277 recurrenceList.clear();
278 FinalNodeOrder.clear();
279 schedule.clear();
Tanya Lattnerced82222004-11-16 21:31:37 +0000280 defMap.clear();
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000281 //Clean up. Nuke old MachineBB and llvmBB
282 //BasicBlock *llvmBB = (BasicBlock*) (*BI)->getBasicBlock();
283 //Function *parent = (Function*) llvmBB->getParent();
284 //Should't std::find work??
285 //parent->getBasicBlockList().erase(std::find(parent->getBasicBlockList().begin(), parent->getBasicBlockList().end(), *llvmBB));
286 //parent->getBasicBlockList().erase(llvmBB);
287
288 //delete(llvmBB);
289 //delete(*BI);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000290 }
Tanya Lattner9532ab92005-03-23 01:47:20 +0000291
292 alarm(0);
Tanya Lattner4f839cc2003-08-28 17:12:14 +0000293 return Changed;
294}
Brian Gaeked0fde302003-11-11 22:41:34 +0000295
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000296bool ModuloSchedulingPass::CreateDefMap(MachineBasicBlock *BI) {
Tanya Lattnerced82222004-11-16 21:31:37 +0000297 defaultInst = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000298
Tanya Lattnerced82222004-11-16 21:31:37 +0000299 for(MachineBasicBlock::iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
300 for(unsigned opNum = 0; opNum < I->getNumOperands(); ++opNum) {
301 const MachineOperand &mOp = I->getOperand(opNum);
302 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
Tanya Lattnere1df2122004-11-22 20:41:24 +0000303 //assert if this is the second def we have seen
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000304 //DEBUG(std::cerr << "Putting " << *(mOp.getVRegValue()) << " into map\n");
Tanya Lattnere1df2122004-11-22 20:41:24 +0000305 assert(!defMap.count(mOp.getVRegValue()) && "Def already in the map");
306
Tanya Lattnerced82222004-11-16 21:31:37 +0000307 defMap[mOp.getVRegValue()] = &*I;
308 }
309
310 //See if we can use this Value* as our defaultInst
311 if(!defaultInst && mOp.getType() == MachineOperand::MO_VirtualRegister) {
312 Value *V = mOp.getVRegValue();
313 if(!isa<TmpInstruction>(V) && !isa<Argument>(V) && !isa<Constant>(V) && !isa<PHINode>(V))
314 defaultInst = (Instruction*) V;
315 }
316 }
317 }
Tanya Lattnere1df2122004-11-22 20:41:24 +0000318
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000319 if(!defaultInst)
320 return false;
321
322 return true;
Tanya Lattnerced82222004-11-16 21:31:37 +0000323
324}
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000325/// This function checks if a Machine Basic Block is valid for modulo
326/// scheduling. This means that it has no control flow (if/else or
327/// calls) in the block. Currently ModuloScheduling only works on
328/// single basic block loops.
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000329bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
330
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000331 bool isLoop = false;
332
333 //Check first if its a valid loop
334 for(succ_const_iterator I = succ_begin(BI->getBasicBlock()),
335 E = succ_end(BI->getBasicBlock()); I != E; ++I) {
336 if (*I == BI->getBasicBlock()) // has single block loop
337 isLoop = true;
338 }
339
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000340 if(!isLoop)
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000341 return false;
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000342
343 //Check that we have a conditional branch (avoiding MS infinite loops)
344 if(BranchInst *b = dyn_cast<BranchInst>(((BasicBlock*) BI->getBasicBlock())->getTerminator()))
345 if(b->isUnconditional())
346 return false;
347
Tanya Lattnere1df2122004-11-22 20:41:24 +0000348 //Check size of our basic block.. make sure we have more then just the terminator in it
349 if(BI->getBasicBlock()->size() == 1)
350 return false;
351
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000352
353 //Increase number of single basic block loops for stats
354 ++SingleBBLoops;
355
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000356 //Get Target machine instruction info
357 const TargetInstrInfo *TMI = target.getInstrInfo();
358
Tanya Lattner9532ab92005-03-23 01:47:20 +0000359 //Check each instruction and look for calls, keep map to get index later
360 std::map<const MachineInstr*, unsigned> indexMap;
361
362 unsigned count = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000363 for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000364 //Get opcode to check instruction type
365 MachineOpCode OC = I->getOpcode();
366 if(TMI->isCall(OC))
367 return false;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000368 //Look for conditional move
369 if(OC == V9::MOVRZr || OC == V9::MOVRZi || OC == V9::MOVRLEZr || OC == V9::MOVRLEZi
370 || OC == V9::MOVRLZr || OC == V9::MOVRLZi || OC == V9::MOVRNZr || OC == V9::MOVRNZi
371 || OC == V9::MOVRGZr || OC == V9::MOVRGZi || OC == V9::MOVRGEZr
372 || OC == V9::MOVRGEZi || OC == V9::MOVLEr || OC == V9::MOVLEi || OC == V9::MOVLEUr
373 || OC == V9::MOVLEUi || OC == V9::MOVFLEr || OC == V9::MOVFLEi
374 || OC == V9::MOVNEr || OC == V9::MOVNEi || OC == V9::MOVNEGr || OC == V9::MOVNEGi
375 || OC == V9::MOVFNEr || OC == V9::MOVFNEi)
376 return false;
Tanya Lattner9532ab92005-03-23 01:47:20 +0000377
378 indexMap[I] = count;
379
380 if(TMI->isNop(OC))
381 continue;
382
383 ++count;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000384 }
Tanya Lattner9532ab92005-03-23 01:47:20 +0000385
386 //Apply a simple pattern match to make sure this loop can be modulo scheduled
387 //This means only loops with a branch associated to the iteration count
388
389 //Get the branch
390 BranchInst *b = dyn_cast<BranchInst>(((BasicBlock*) BI->getBasicBlock())->getTerminator());
391
392 //Get the condition for the branch (we already checked if it was conditional)
393 Value *cond = b->getCondition();
394
395 DEBUG(std::cerr << "Condition: " << *cond << "\n");
396
397 //List of instructions associated with induction variable
398 std::set<Instruction*> indVar;
399 std::vector<Instruction*> stack;
400
401 BasicBlock *BB = (BasicBlock*) BI->getBasicBlock();
402
403 //Add branch
404 indVar.insert(b);
405
406 if(Instruction *I = dyn_cast<Instruction>(cond))
407 if(I->getParent() == BB) {
408 if (!assocIndVar(I, indVar, stack, BB))
409 return false;
410 }
411 else
412 return false;
413 else
414 return false;
415
416 //The indVar set must be >= 3 instructions for this loop to match (FIX ME!)
417 if(indVar.size() < 3 )
418 return false;
419
420 //Dump out instructions associate with indvar for debug reasons
421 DEBUG(for(std::set<Instruction*>::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
422 std::cerr << **N << "\n";
423 });
424
425 //Convert list of LLVM Instructions to list of Machine instructions
426 std::map<const MachineInstr*, unsigned> mIndVar;
427 for(std::set<Instruction*>::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
428 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(*N);
429 for (unsigned j = 0; j < tempMvec.size(); j++) {
430 MachineOpCode OC = (tempMvec[j])->getOpcode();
431 if(TMI->isNop(OC))
432 continue;
433 if(!indexMap.count(tempMvec[j]))
434 continue;
435 mIndVar[(MachineInstr*) tempMvec[j]] = indexMap[(MachineInstr*) tempMvec[j]];
436 DEBUG(std::cerr << *(tempMvec[j]) << " at index " << indexMap[(MachineInstr*) tempMvec[j]] << "\n");
437 }
438 }
439
440 //Must have some guts to the loop body
441 if(mIndVar.size() >= (BI->size()-2))
442 return false;
443
444 //Put into a map for future access
445 indVarInstrs[BI] = mIndVar;
446
447 return true;
448}
449
450bool ModuloSchedulingPass::assocIndVar(Instruction *I, std::set<Instruction*> &indVar,
451 std::vector<Instruction*> &stack, BasicBlock *BB) {
452
453 stack.push_back(I);
454
455 //If this is a phi node, check if its the canonical indvar
456 if(PHINode *PN = dyn_cast<PHINode>(I)) {
457 if (Instruction *Inc =
458 dyn_cast<Instruction>(PN->getIncomingValueForBlock(BB)))
459 if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN)
460 if (ConstantInt *CI = dyn_cast<ConstantInt>(Inc->getOperand(1)))
461 if (CI->equalsInt(1)) {
462 //We have found the indvar, so add the stack, and inc instruction to the set
463 indVar.insert(stack.begin(), stack.end());
464 indVar.insert(Inc);
465 stack.pop_back();
466 return true;
467 }
468 return false;
469 }
470 else {
471 //Loop over each of the instructions operands, check if they are an instruction and in this BB
472 for(unsigned i = 0; i < I->getNumOperands(); ++i) {
473 if(Instruction *N = dyn_cast<Instruction>(I->getOperand(i))) {
474 if(N->getParent() == BB)
475 if(!assocIndVar(N, indVar, stack, BB))
476 return false;
477 }
478 }
479 }
480
481 stack.pop_back();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000482 return true;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000483}
484
485//ResMII is calculated by determining the usage count for each resource
486//and using the maximum.
487//FIXME: In future there should be a way to get alternative resources
488//for each instruction
489int ModuloSchedulingPass::calculateResMII(const MachineBasicBlock *BI) {
490
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000491 TIME_REGION(X, "calculateResMII");
492
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000493 const TargetInstrInfo *mii = target.getInstrInfo();
494 const TargetSchedInfo *msi = target.getSchedInfo();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000495
496 int ResMII = 0;
497
498 //Map to keep track of usage count of each resource
499 std::map<unsigned, unsigned> resourceUsageCount;
500
501 for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
502
503 //Get resource usage for this instruction
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000504 InstrRUsage rUsage = msi->getInstrRUsage(I->getOpcode());
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000505 std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
506
507 //Loop over resources in each cycle and increments their usage count
508 for(unsigned i=0; i < resources.size(); ++i)
509 for(unsigned j=0; j < resources[i].size(); ++j) {
510 if( resourceUsageCount.find(resources[i][j]) == resourceUsageCount.end()) {
511 resourceUsageCount[resources[i][j]] = 1;
512 }
513 else {
514 resourceUsageCount[resources[i][j]] = resourceUsageCount[resources[i][j]] + 1;
515 }
516 }
517 }
518
519 //Find maximum usage count
520
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000521 //Get max number of instructions that can be issued at once. (FIXME)
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000522 int issueSlots = msi->maxNumIssueTotal;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000523
524 for(std::map<unsigned,unsigned>::iterator RB = resourceUsageCount.begin(), RE = resourceUsageCount.end(); RB != RE; ++RB) {
Tanya Lattner4cffb582004-05-26 06:27:18 +0000525
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000526 //Get the total number of the resources in our cpu
Tanya Lattner4cffb582004-05-26 06:27:18 +0000527 int resourceNum = CPUResource::getCPUResource(RB->first)->maxNumUsers;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000528
529 //Get total usage count for this resources
530 unsigned usageCount = RB->second;
531
532 //Divide the usage count by either the max number we can issue or the number of
533 //resources (whichever is its upper bound)
534 double finalUsageCount;
Tanya Lattner4cffb582004-05-26 06:27:18 +0000535 if( resourceNum <= issueSlots)
536 finalUsageCount = ceil(1.0 * usageCount / resourceNum);
537 else
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000538 finalUsageCount = ceil(1.0 * usageCount / issueSlots);
539
540
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000541 //Only keep track of the max
542 ResMII = std::max( (int) finalUsageCount, ResMII);
543
544 }
545
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000546 return ResMII;
547
548}
549
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000550/// calculateRecMII - Calculates the value of the highest recurrence
551/// By value we mean the total latency
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000552int ModuloSchedulingPass::calculateRecMII(MSchedGraph *graph, int MII) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000553 /*std::vector<MSchedGraphNode*> vNodes;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000554 //Loop over all nodes in the graph
555 for(MSchedGraph::iterator I = graph->begin(), E = graph->end(); I != E; ++I) {
556 findAllReccurrences(I->second, vNodes, MII);
557 vNodes.clear();
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000558 }*/
559
560 TIME_REGION(X, "calculateRecMII");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000561
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000562 findAllCircuits(graph, MII);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000563 int RecMII = 0;
564
Tanya Lattner9532ab92005-03-23 01:47:20 +0000565 for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::iterator I = recurrenceList.begin(), E=recurrenceList.end(); I !=E; ++I) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000566 RecMII = std::max(RecMII, I->first);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000567 }
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000568
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000569 return MII;
570}
571
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000572/// calculateNodeAttributes - The following properties are calculated for
573/// each node in the dependence graph: ASAP, ALAP, Depth, Height, and
574/// MOB.
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000575void ModuloSchedulingPass::calculateNodeAttributes(MSchedGraph *graph, int MII) {
576
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000577 TIME_REGION(X, "calculateNodeAttributes");
578
Tanya Lattner260652a2004-10-30 00:39:07 +0000579 assert(nodeToAttributesMap.empty() && "Node attribute map was not cleared");
580
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000581 //Loop over the nodes and add them to the map
582 for(MSchedGraph::iterator I = graph->begin(), E = graph->end(); I != E; ++I) {
Tanya Lattner260652a2004-10-30 00:39:07 +0000583
584 DEBUG(std::cerr << "Inserting node into attribute map: " << *I->second << "\n");
585
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000586 //Assert if its already in the map
Tanya Lattner260652a2004-10-30 00:39:07 +0000587 assert(nodeToAttributesMap.count(I->second) == 0 &&
588 "Node attributes are already in the map");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000589
590 //Put into the map with default attribute values
591 nodeToAttributesMap[I->second] = MSNodeAttributes();
592 }
593
594 //Create set to deal with reccurrences
595 std::set<MSchedGraphNode*> visitedNodes;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000596
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000597 //Now Loop over map and calculate the node attributes
598 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000599 calculateASAP(I->first, MII, (MSchedGraphNode*) 0);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000600 visitedNodes.clear();
601 }
602
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000603 int maxASAP = findMaxASAP();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000604 //Calculate ALAP which depends on ASAP being totally calculated
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000605 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
606 calculateALAP(I->first, MII, maxASAP, (MSchedGraphNode*) 0);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000607 visitedNodes.clear();
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000608 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000609
610 //Calculate MOB which depends on ASAP being totally calculated, also do depth and height
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000611 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
612 (I->second).MOB = std::max(0,(I->second).ALAP - (I->second).ASAP);
613
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000614 DEBUG(std::cerr << "MOB: " << (I->second).MOB << " (" << *(I->first) << ")\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000615 calculateDepth(I->first, (MSchedGraphNode*) 0);
616 calculateHeight(I->first, (MSchedGraphNode*) 0);
617 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000618
619
620}
621
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000622/// ignoreEdge - Checks to see if this edge of a recurrence should be ignored or not
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000623bool ModuloSchedulingPass::ignoreEdge(MSchedGraphNode *srcNode, MSchedGraphNode *destNode) {
624 if(destNode == 0 || srcNode ==0)
625 return false;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000626
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000627 bool findEdge = edgesToIgnore.count(std::make_pair(srcNode, destNode->getInEdgeNum(srcNode)));
Tanya Lattner4cffb582004-05-26 06:27:18 +0000628
Tanya Lattner9532ab92005-03-23 01:47:20 +0000629 DEBUG(std::cerr << "Ignoring edge? from: " << *srcNode << " to " << *destNode << "\n");
630
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000631 return findEdge;
632}
633
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000634
635/// calculateASAP - Calculates the
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000636int ModuloSchedulingPass::calculateASAP(MSchedGraphNode *node, int MII, MSchedGraphNode *destNode) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000637
638 DEBUG(std::cerr << "Calculating ASAP for " << *node << "\n");
639
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000640 //Get current node attributes
641 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
642
643 if(attributes.ASAP != -1)
644 return attributes.ASAP;
645
646 int maxPredValue = 0;
647
648 //Iterate over all of the predecessors and find max
649 for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000650
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000651 //Only process if we are not ignoring the edge
652 if(!ignoreEdge(*P, node)) {
653 int predASAP = -1;
654 predASAP = calculateASAP(*P, MII, node);
655
656 assert(predASAP != -1 && "ASAP has not been calculated");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000657 int iteDiff = node->getInEdge(*P).getIteDiff();
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000658
659 int currentPredValue = predASAP + (*P)->getLatency() - (iteDiff * MII);
660 DEBUG(std::cerr << "pred ASAP: " << predASAP << ", iteDiff: " << iteDiff << ", PredLatency: " << (*P)->getLatency() << ", Current ASAP pred: " << currentPredValue << "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000661 maxPredValue = std::max(maxPredValue, currentPredValue);
662 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000663 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000664
665 attributes.ASAP = maxPredValue;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000666
667 DEBUG(std::cerr << "ASAP: " << attributes.ASAP << " (" << *node << ")\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000668
669 return maxPredValue;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000670}
671
672
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000673int ModuloSchedulingPass::calculateALAP(MSchedGraphNode *node, int MII,
674 int maxASAP, MSchedGraphNode *srcNode) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000675
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000676 DEBUG(std::cerr << "Calculating ALAP for " << *node << "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000677
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000678 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
679
680 if(attributes.ALAP != -1)
681 return attributes.ALAP;
682
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000683 if(node->hasSuccessors()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000684
685 //Trying to deal with the issue where the node has successors, but
686 //we are ignoring all of the edges to them. So this is my hack for
687 //now.. there is probably a more elegant way of doing this (FIXME)
688 bool processedOneEdge = false;
689
690 //FIXME, set to something high to start
691 int minSuccValue = 9999999;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000692
693 //Iterate over all of the predecessors and fine max
694 for(MSchedGraphNode::succ_iterator P = node->succ_begin(),
695 E = node->succ_end(); P != E; ++P) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000696
697 //Only process if we are not ignoring the edge
698 if(!ignoreEdge(node, *P)) {
699 processedOneEdge = true;
700 int succALAP = -1;
701 succALAP = calculateALAP(*P, MII, maxASAP, node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000702
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000703 assert(succALAP != -1 && "Successors ALAP should have been caclulated");
704
705 int iteDiff = P.getEdge().getIteDiff();
706
707 int currentSuccValue = succALAP - node->getLatency() + iteDiff * MII;
708
709 DEBUG(std::cerr << "succ ALAP: " << succALAP << ", iteDiff: " << iteDiff << ", SuccLatency: " << (*P)->getLatency() << ", Current ALAP succ: " << currentSuccValue << "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000710
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000711 minSuccValue = std::min(minSuccValue, currentSuccValue);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000712 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000713 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000714
715 if(processedOneEdge)
716 attributes.ALAP = minSuccValue;
717
718 else
719 attributes.ALAP = maxASAP;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000720 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000721 else
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000722 attributes.ALAP = maxASAP;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000723
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000724 DEBUG(std::cerr << "ALAP: " << attributes.ALAP << " (" << *node << ")\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000725
726 if(attributes.ALAP < 0)
727 attributes.ALAP = 0;
728
729 return attributes.ALAP;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000730}
731
732int ModuloSchedulingPass::findMaxASAP() {
733 int maxASAP = 0;
734
735 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
736 E = nodeToAttributesMap.end(); I != E; ++I)
737 maxASAP = std::max(maxASAP, I->second.ASAP);
738 return maxASAP;
739}
740
741
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000742int ModuloSchedulingPass::calculateHeight(MSchedGraphNode *node,MSchedGraphNode *srcNode) {
743
744 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000745
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000746 if(attributes.height != -1)
747 return attributes.height;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000748
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000749 int maxHeight = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000750
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000751 //Iterate over all of the predecessors and find max
752 for(MSchedGraphNode::succ_iterator P = node->succ_begin(),
753 E = node->succ_end(); P != E; ++P) {
754
755
756 if(!ignoreEdge(node, *P)) {
757 int succHeight = calculateHeight(*P, node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000758
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000759 assert(succHeight != -1 && "Successors Height should have been caclulated");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000760
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000761 int currentHeight = succHeight + node->getLatency();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000762 maxHeight = std::max(maxHeight, currentHeight);
763 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000764 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000765 attributes.height = maxHeight;
766 DEBUG(std::cerr << "Height: " << attributes.height << " (" << *node << ")\n");
767 return maxHeight;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000768}
769
770
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000771int ModuloSchedulingPass::calculateDepth(MSchedGraphNode *node,
772 MSchedGraphNode *destNode) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000773
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000774 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000775
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000776 if(attributes.depth != -1)
777 return attributes.depth;
778
779 int maxDepth = 0;
780
781 //Iterate over all of the predecessors and fine max
782 for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) {
783
784 if(!ignoreEdge(*P, node)) {
785 int predDepth = -1;
786 predDepth = calculateDepth(*P, node);
787
788 assert(predDepth != -1 && "Predecessors ASAP should have been caclulated");
789
790 int currentDepth = predDepth + (*P)->getLatency();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000791 maxDepth = std::max(maxDepth, currentDepth);
792 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000793 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000794 attributes.depth = maxDepth;
795
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000796 DEBUG(std::cerr << "Depth: " << attributes.depth << " (" << *node << "*)\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000797 return maxDepth;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000798}
799
800
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000801
802void ModuloSchedulingPass::addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode *srcBENode, MSchedGraphNode *destBENode) {
803 //Check to make sure that this recurrence is unique
804 bool same = false;
805
806
807 //Loop over all recurrences already in our list
808 for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::iterator R = recurrenceList.begin(), RE = recurrenceList.end(); R != RE; ++R) {
809
810 bool all_same = true;
811 //First compare size
812 if(R->second.size() == recurrence.size()) {
813
814 for(std::vector<MSchedGraphNode*>::const_iterator node = R->second.begin(), end = R->second.end(); node != end; ++node) {
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +0000815 if(std::find(recurrence.begin(), recurrence.end(), *node) == recurrence.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000816 all_same = all_same && false;
817 break;
818 }
819 else
820 all_same = all_same && true;
821 }
822 if(all_same) {
823 same = true;
824 break;
825 }
826 }
827 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000828
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000829 if(!same) {
Tanya Lattner4cffb582004-05-26 06:27:18 +0000830 srcBENode = recurrence.back();
831 destBENode = recurrence.front();
832
833 //FIXME
834 if(destBENode->getInEdge(srcBENode).getIteDiff() == 0) {
835 //DEBUG(std::cerr << "NOT A BACKEDGE\n");
836 //find actual backedge HACK HACK
837 for(unsigned i=0; i< recurrence.size()-1; ++i) {
838 if(recurrence[i+1]->getInEdge(recurrence[i]).getIteDiff() == 1) {
839 srcBENode = recurrence[i];
840 destBENode = recurrence[i+1];
841 break;
842 }
843
844 }
845
846 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000847 DEBUG(std::cerr << "Back Edge to Remove: " << *srcBENode << " to " << *destBENode << "\n");
848 edgesToIgnore.insert(std::make_pair(srcBENode, destBENode->getInEdgeNum(srcBENode)));
849 recurrenceList.insert(std::make_pair(II, recurrence));
850 }
851
852}
853
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000854int CircCount;
855
856void ModuloSchedulingPass::unblock(MSchedGraphNode *u, std::set<MSchedGraphNode*> &blocked,
857 std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B) {
858
859 //Unblock u
860 DEBUG(std::cerr << "Unblocking: " << *u << "\n");
861 blocked.erase(u);
862
863 //std::set<MSchedGraphNode*> toErase;
864 while (!B[u].empty()) {
865 MSchedGraphNode *W = *B[u].begin();
866 B[u].erase(W);
867 //toErase.insert(*W);
868 DEBUG(std::cerr << "Removed: " << *W << "from B-List\n");
869 if(blocked.count(W))
870 unblock(W, blocked, B);
871 }
872
873}
874
875bool ModuloSchedulingPass::circuit(MSchedGraphNode *v, std::vector<MSchedGraphNode*> &stack,
876 std::set<MSchedGraphNode*> &blocked, std::vector<MSchedGraphNode*> &SCC,
877 MSchedGraphNode *s, std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B,
878 int II, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes) {
879 bool f = false;
880
881 DEBUG(std::cerr << "Finding Circuits Starting with: ( " << v << ")"<< *v << "\n");
882
883 //Push node onto the stack
884 stack.push_back(v);
885
886 //block this node
887 blocked.insert(v);
888
889 //Loop over all successors of node v that are in the scc, create Adjaceny list
890 std::set<MSchedGraphNode*> AkV;
891 for(MSchedGraphNode::succ_iterator I = v->succ_begin(), E = v->succ_end(); I != E; ++I) {
892 if((std::find(SCC.begin(), SCC.end(), *I) != SCC.end())) {
893 AkV.insert(*I);
894 }
895 }
896
897 for(std::set<MSchedGraphNode*>::iterator I = AkV.begin(), E = AkV.end(); I != E; ++I) {
898 if(*I == s) {
899 //We have a circuit, so add it to our list
900
901 std::vector<MSchedGraphNode*> recc;
902 //Dump recurrence for now
903 DEBUG(std::cerr << "Starting Recc\n");
904
905 int totalDelay = 0;
906 int totalDistance = 0;
907 MSchedGraphNode *lastN = 0;
Tanya Lattner9532ab92005-03-23 01:47:20 +0000908 MSchedGraphNode *start = 0;
909 MSchedGraphNode *end = 0;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000910
911 //Loop over recurrence, get delay and distance
912 for(std::vector<MSchedGraphNode*>::iterator N = stack.begin(), NE = stack.end(); N != NE; ++N) {
913 totalDelay += (*N)->getLatency();
914 if(lastN) {
Tanya Lattner9532ab92005-03-23 01:47:20 +0000915 int iteDiff = (*N)->getInEdge(lastN).getIteDiff();
916 totalDistance += iteDiff;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000917
Tanya Lattner9532ab92005-03-23 01:47:20 +0000918 if(iteDiff > 0) {
919 start = lastN;
920 end = *N;
921 }
922 }
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000923 //Get the original node
924 lastN = *N;
925 recc.push_back(newNodes[*N]);
926
927 DEBUG(std::cerr << *lastN << "\n");
928 }
929
930 //Get the loop edge
931 totalDistance += lastN->getIteDiff(*stack.begin());
932
933 DEBUG(std::cerr << "End Recc\n");
934 f = true;
935 CircCount++;
936
Tanya Lattner9532ab92005-03-23 01:47:20 +0000937 if(start && end) {
938 //Insert reccurrence into the list
939 DEBUG(std::cerr << "Ignore Edge from!!: " << *start << " to " << *end << "\n");
940 edgesToIgnore.insert(std::make_pair(newNodes[start], (newNodes[end])->getInEdgeNum(newNodes[start])));
941 }
942 else {
943 //Insert reccurrence into the list
944 DEBUG(std::cerr << "Ignore Edge from: " << *lastN << " to " << **stack.begin() << "\n");
945 edgesToIgnore.insert(std::make_pair(newNodes[lastN], newNodes[(*stack.begin())]->getInEdgeNum(newNodes[lastN])));
946
947 }
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000948 //Adjust II until we get close to the inequality delay - II*distance <= 0
949 int RecMII = II; //Starting value
950 int value = totalDelay-(RecMII * totalDistance);
951 int lastII = II;
952 while(value <= 0) {
953
954 lastII = RecMII;
955 RecMII--;
956 value = totalDelay-(RecMII * totalDistance);
957 }
958
959 recurrenceList.insert(std::make_pair(lastII, recc));
960
961 }
962 else if(!blocked.count(*I)) {
963 if(circuit(*I, stack, blocked, SCC, s, B, II, newNodes))
964 f = true;
965 }
966 else
967 DEBUG(std::cerr << "Blocked: " << **I << "\n");
968 }
969
970
971 if(f) {
972 unblock(v, blocked, B);
973 }
974 else {
975 for(std::set<MSchedGraphNode*>::iterator I = AkV.begin(), E = AkV.end(); I != E; ++I)
976 B[*I].insert(v);
977
978 }
979
980 //Pop v
981 stack.pop_back();
982
983 return f;
984
985}
986
987void ModuloSchedulingPass::findAllCircuits(MSchedGraph *g, int II) {
988
989 CircCount = 0;
990
991 //Keep old to new node mapping information
992 std::map<MSchedGraphNode*, MSchedGraphNode*> newNodes;
993
994 //copy the graph
995 MSchedGraph *MSG = new MSchedGraph(*g, newNodes);
996
997 DEBUG(std::cerr << "Finding All Circuits\n");
998
999 //Set of blocked nodes
1000 std::set<MSchedGraphNode*> blocked;
1001
1002 //Stack holding current circuit
1003 std::vector<MSchedGraphNode*> stack;
1004
1005 //Map for B Lists
1006 std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > B;
1007
1008 //current node
1009 MSchedGraphNode *s;
1010
1011
1012 //Iterate over the graph until its down to one node or empty
1013 while(MSG->size() > 1) {
1014
1015 //Write Graph out to file
1016 //WriteGraphToFile(std::cerr, "Graph" + utostr(MSG->size()), MSG);
1017
1018 DEBUG(std::cerr << "Graph Size: " << MSG->size() << "\n");
1019 DEBUG(std::cerr << "Finding strong component Vk with least vertex\n");
1020
1021 //Iterate over all the SCCs in the graph
1022 std::set<MSchedGraphNode*> Visited;
1023 std::vector<MSchedGraphNode*> Vk;
1024 MSchedGraphNode* s = 0;
1025
1026 //Find scc with the least vertex
1027 for (MSchedGraph::iterator GI = MSG->begin(), E = MSG->end(); GI != E; ++GI)
1028 if (Visited.insert(GI->second).second) {
1029 for (scc_iterator<MSchedGraphNode*> SCCI = scc_begin(GI->second),
1030 E = scc_end(GI->second); SCCI != E; ++SCCI) {
1031 std::vector<MSchedGraphNode*> &nextSCC = *SCCI;
1032
1033 if (Visited.insert(nextSCC[0]).second) {
1034 Visited.insert(nextSCC.begin()+1, nextSCC.end());
1035
1036 DEBUG(std::cerr << "SCC size: " << nextSCC.size() << "\n");
1037
1038 //Ignore self loops
1039 if(nextSCC.size() > 1) {
Tanya Lattner9532ab92005-03-23 01:47:20 +00001040
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001041 //Get least vertex in Vk
1042 if(!s) {
1043 s = nextSCC[0];
1044 Vk = nextSCC;
1045 }
1046
1047 for(unsigned i = 0; i < nextSCC.size(); ++i) {
1048 if(nextSCC[i] < s) {
1049 s = nextSCC[i];
1050 Vk = nextSCC;
1051 }
1052 }
1053 }
1054 }
1055 }
1056 }
1057
1058
1059
1060 //Process SCC
1061 DEBUG(for(std::vector<MSchedGraphNode*>::iterator N = Vk.begin(), NE = Vk.end();
1062 N != NE; ++N) { std::cerr << *((*N)->getInst()); });
1063
1064 //Iterate over all nodes in this scc
1065 for(std::vector<MSchedGraphNode*>::iterator N = Vk.begin(), NE = Vk.end();
1066 N != NE; ++N) {
1067 blocked.erase(*N);
1068 B[*N].clear();
1069 }
1070 if(Vk.size() > 1) {
1071 circuit(s, stack, blocked, Vk, s, B, II, newNodes);
1072
1073 //Find all nodes up to s and delete them
1074 std::vector<MSchedGraphNode*> nodesToRemove;
1075 nodesToRemove.push_back(s);
1076 for(MSchedGraph::iterator N = MSG->begin(), NE = MSG->end(); N != NE; ++N) {
1077 if(N->second < s )
1078 nodesToRemove.push_back(N->second);
1079 }
1080 for(std::vector<MSchedGraphNode*>::iterator N = nodesToRemove.begin(), NE = nodesToRemove.end(); N != NE; ++N) {
1081 DEBUG(std::cerr << "Deleting Node: " << **N << "\n");
1082 MSG->deleteNode(*N);
1083 }
1084 }
1085 else
1086 break;
1087 }
1088 DEBUG(std::cerr << "Num Circuits found: " << CircCount << "\n");
1089}
1090
1091
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001092void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node,
1093 std::vector<MSchedGraphNode*> &visitedNodes,
1094 int II) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001095
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001096
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001097 if(std::find(visitedNodes.begin(), visitedNodes.end(), node) != visitedNodes.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001098 std::vector<MSchedGraphNode*> recurrence;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001099 bool first = true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001100 int delay = 0;
1101 int distance = 0;
1102 int RecMII = II; //Starting value
1103 MSchedGraphNode *last = node;
Chris Lattner46c2b3a2004-08-04 03:51:55 +00001104 MSchedGraphNode *srcBackEdge = 0;
1105 MSchedGraphNode *destBackEdge = 0;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001106
1107
1108
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001109 for(std::vector<MSchedGraphNode*>::iterator I = visitedNodes.begin(), E = visitedNodes.end();
1110 I !=E; ++I) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001111
1112 if(*I == node)
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001113 first = false;
1114 if(first)
1115 continue;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001116
1117 delay = delay + (*I)->getLatency();
1118
1119 if(*I != node) {
1120 int diff = (*I)->getInEdge(last).getIteDiff();
1121 distance += diff;
1122 if(diff > 0) {
1123 srcBackEdge = last;
1124 destBackEdge = *I;
1125 }
1126 }
1127
1128 recurrence.push_back(*I);
1129 last = *I;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001130 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001131
1132
1133
1134 //Get final distance calc
1135 distance += node->getInEdge(last).getIteDiff();
Tanya Lattnere1df2122004-11-22 20:41:24 +00001136 DEBUG(std::cerr << "Reccurrence Distance: " << distance << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001137
1138 //Adjust II until we get close to the inequality delay - II*distance <= 0
1139
1140 int value = delay-(RecMII * distance);
1141 int lastII = II;
1142 while(value <= 0) {
1143
1144 lastII = RecMII;
1145 RecMII--;
1146 value = delay-(RecMII * distance);
1147 }
1148
1149
1150 DEBUG(std::cerr << "Final II for this recurrence: " << lastII << "\n");
1151 addReccurrence(recurrence, lastII, srcBackEdge, destBackEdge);
1152 assert(distance != 0 && "Recurrence distance should not be zero");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001153 return;
1154 }
1155
Tanya Lattner01114742005-01-18 04:15:41 +00001156 unsigned count = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001157 for(MSchedGraphNode::succ_iterator I = node->succ_begin(), E = node->succ_end(); I != E; ++I) {
1158 visitedNodes.push_back(node);
Tanya Lattner01114742005-01-18 04:15:41 +00001159 //if(!edgesToIgnore.count(std::make_pair(node, count)))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001160 findAllReccurrences(*I, visitedNodes, II);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001161 visitedNodes.pop_back();
Tanya Lattner01114742005-01-18 04:15:41 +00001162 count++;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001163 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001164}
1165
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001166void ModuloSchedulingPass::searchPath(MSchedGraphNode *node,
1167 std::vector<MSchedGraphNode*> &path,
1168 std::set<MSchedGraphNode*> &nodesToAdd) {
1169 //Push node onto the path
1170 path.push_back(node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001171
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001172 //Loop over all successors and see if there is a path from this node to
1173 //a recurrence in the partial order, if so.. add all nodes to be added to recc
1174 for(MSchedGraphNode::succ_iterator S = node->succ_begin(), SE = node->succ_end(); S != SE;
1175 ++S) {
1176
1177 //If this node exists in a recurrence already in the partial order, then add all
1178 //nodes in the path to the set of nodes to add
1179 //Check if its already in our partial order, if not add it to the final vector
1180 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(),
1181 PE = partialOrder.end(); PO != PE; ++PO) {
1182
1183 //Check if we should ignore this edge first
1184 if(ignoreEdge(node,*S))
1185 continue;
1186
1187 if(PO->count(*S)) {
1188 nodesToAdd.insert(*S);
1189 }
Tanya Lattner9532ab92005-03-23 01:47:20 +00001190 //terminate
1191 else
1192 searchPath(*S, path, nodesToAdd);
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001193 }
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001194 }
1195
1196 //Pop Node off the path
1197 path.pop_back();
1198}
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001199
Tanya Lattner9532ab92005-03-23 01:47:20 +00001200void ModuloSchedulingPass::pathToRecc(MSchedGraphNode *node,
1201 std::vector<MSchedGraphNode*> &path,
1202 std::set<MSchedGraphNode*> &poSet,
1203 std::set<MSchedGraphNode*> &lastNodes) {
1204 //Push node onto the path
1205 path.push_back(node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001206
Tanya Lattner9532ab92005-03-23 01:47:20 +00001207 DEBUG(std::cerr << "Current node: " << *node << "\n");
1208
1209 //Loop over all successors and see if there is a path from this node to
1210 //a recurrence in the partial order, if so.. add all nodes to be added to recc
1211 for(MSchedGraphNode::succ_iterator S = node->succ_begin(), SE = node->succ_end(); S != SE;
1212 ++S) {
1213 DEBUG(std::cerr << "Succ:" << **S << "\n");
1214 //Check if we should ignore this edge first
1215 if(ignoreEdge(node,*S))
1216 continue;
1217
1218 if(poSet.count(*S)) {
1219 DEBUG(std::cerr << "Found path to recc from no pred\n");
1220 //Loop over path, if it exists in lastNodes, then add to poset, and remove from lastNodes
1221 for(std::vector<MSchedGraphNode*>::iterator I = path.begin(), IE = path.end(); I != IE; ++I) {
1222 if(lastNodes.count(*I)) {
1223 DEBUG(std::cerr << "Inserting node into recc: " << **I << "\n");
1224 poSet.insert(*I);
1225 lastNodes.erase(*I);
1226 }
1227 }
1228 }
1229 else
1230 pathToRecc(*S, path, poSet, lastNodes);
1231 }
1232
1233 //Pop Node off the path
1234 path.pop_back();
1235}
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001236
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001237void ModuloSchedulingPass::computePartialOrder() {
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001238
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001239 TIME_REGION(X, "calculatePartialOrder");
1240
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001241 //Only push BA branches onto the final node order, we put other branches after it
1242 //FIXME: Should we really be pushing branches on it a specific order instead of relying
1243 //on BA being there?
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001244 std::vector<MSchedGraphNode*> branches;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001245
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001246 //Steps to add a recurrence to the partial order
1247 // 1) Find reccurrence with the highest RecMII. Add it to the partial order.
1248 // 2) For each recurrence with decreasing RecMII, add it to the partial order along with
1249 // any nodes that connect this recurrence to recurrences already in the partial order
1250 for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::reverse_iterator
1251 I = recurrenceList.rbegin(), E=recurrenceList.rend(); I !=E; ++I) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001252
Tanya Lattner260652a2004-10-30 00:39:07 +00001253 std::set<MSchedGraphNode*> new_recurrence;
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001254
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001255 //Loop through recurrence and remove any nodes already in the partial order
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001256 for(std::vector<MSchedGraphNode*>::const_iterator N = I->second.begin(),
1257 NE = I->second.end(); N != NE; ++N) {
1258
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001259 bool found = false;
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001260 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(),
1261 PE = partialOrder.end(); PO != PE; ++PO) {
Tanya Lattner260652a2004-10-30 00:39:07 +00001262 if(PO->count(*N))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001263 found = true;
1264 }
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001265
1266 //Check if its a branch, and remove to handle special
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001267 if(!found) {
Tanya Lattner9532ab92005-03-23 01:47:20 +00001268 if((*N)->isBranch() && !(*N)->hasPredecessors()) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001269 branches.push_back(*N);
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001270 }
1271 else
1272 new_recurrence.insert(*N);
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001273 }
1274
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001275 }
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001276
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001277
1278 if(new_recurrence.size() > 0) {
1279
1280 std::vector<MSchedGraphNode*> path;
1281 std::set<MSchedGraphNode*> nodesToAdd;
1282
1283 //Add nodes that connect this recurrence to recurrences in the partial path
1284 for(std::set<MSchedGraphNode*>::iterator N = new_recurrence.begin(),
Tanya Lattner9532ab92005-03-23 01:47:20 +00001285 NE = new_recurrence.end(); N != NE; ++N)
1286 searchPath(*N, path, nodesToAdd);
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001287
1288 //Add nodes to this recurrence if they are not already in the partial order
1289 for(std::set<MSchedGraphNode*>::iterator N = nodesToAdd.begin(), NE = nodesToAdd.end();
1290 N != NE; ++N) {
1291 bool found = false;
1292 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(),
1293 PE = partialOrder.end(); PO != PE; ++PO) {
1294 if(PO->count(*N))
1295 found = true;
1296 }
1297 if(!found) {
1298 assert("FOUND CONNECTOR");
1299 new_recurrence.insert(*N);
1300 }
1301 }
1302
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001303 partialOrder.push_back(new_recurrence);
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001304
1305 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001306 }
1307
1308 //Add any nodes that are not already in the partial order
Tanya Lattner260652a2004-10-30 00:39:07 +00001309 //Add them in a set, one set per connected component
1310 std::set<MSchedGraphNode*> lastNodes;
Tanya Lattner9532ab92005-03-23 01:47:20 +00001311 std::set<MSchedGraphNode*> noPredNodes;
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001312 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
1313 E = nodeToAttributesMap.end(); I != E; ++I) {
1314
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001315 bool found = false;
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001316
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001317 //Check if its already in our partial order, if not add it to the final vector
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001318 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(),
1319 PE = partialOrder.end(); PO != PE; ++PO) {
Tanya Lattner260652a2004-10-30 00:39:07 +00001320 if(PO->count(I->first))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001321 found = true;
1322 }
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001323 if(!found) {
Tanya Lattner9532ab92005-03-23 01:47:20 +00001324 if(I->first->isBranch() && !I->first->hasPredecessors()) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001325 if(std::find(branches.begin(), branches.end(), I->first) == branches.end())
1326 branches.push_back(I->first);
1327 }
Tanya Lattner9532ab92005-03-23 01:47:20 +00001328 else {
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001329 lastNodes.insert(I->first);
Tanya Lattner9532ab92005-03-23 01:47:20 +00001330 if(!I->first->hasPredecessors())
1331 noPredNodes.insert(I->first);
1332 }
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001333 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001334 }
1335
Tanya Lattner9532ab92005-03-23 01:47:20 +00001336 //For each node w/out preds, see if there is a path to one of the
1337 //recurrences, and if so add them to that current recc
1338 /*for(std::set<MSchedGraphNode*>::iterator N = noPredNodes.begin(), NE = noPredNodes.end();
1339 N != NE; ++N) {
1340 DEBUG(std::cerr << "No Pred Path from: " << **N << "\n");
1341 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(),
1342 PE = partialOrder.end(); PO != PE; ++PO) {
1343 std::vector<MSchedGraphNode*> path;
1344 pathToRecc(*N, path, *PO, lastNodes);
1345 }
1346 }*/
1347
1348
Tanya Lattner260652a2004-10-30 00:39:07 +00001349 //Break up remaining nodes that are not in the partial order
Tanya Lattner9532ab92005-03-23 01:47:20 +00001350 ///into their connected compoenents
1351 /*while(lastNodes.size() > 0) {
1352 std::set<MSchedGraphNode*> ccSet;
1353 connectedComponentSet(*(lastNodes.begin()),ccSet, lastNodes);
1354 if(ccSet.size() > 0)
1355 partialOrder.push_back(ccSet);
1356 }*/
1357 if(lastNodes.size() > 0)
1358 partialOrder.push_back(lastNodes);
1359
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001360
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001361 //Clean up branches by putting them in final order
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001362 std::map<unsigned, MSchedGraphNode*> branchOrder;
1363 for(std::vector<MSchedGraphNode*>::iterator I = branches.begin(), E = branches.end(); I != E; ++I)
1364 branchOrder[(*I)->getIndex()] = *I;
1365
1366 for(std::map<unsigned, MSchedGraphNode*>::reverse_iterator I = branchOrder.rbegin(), E = branchOrder.rend(); I != E; ++I)
1367 FinalNodeOrder.push_back(I->second);
1368
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001369}
1370
1371
Tanya Lattner260652a2004-10-30 00:39:07 +00001372void ModuloSchedulingPass::connectedComponentSet(MSchedGraphNode *node, std::set<MSchedGraphNode*> &ccSet, std::set<MSchedGraphNode*> &lastNodes) {
1373
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001374//Add to final set
1375if( !ccSet.count(node) && lastNodes.count(node)) {
Tanya Lattner260652a2004-10-30 00:39:07 +00001376 lastNodes.erase(node);
Tanya Lattner9532ab92005-03-23 01:47:20 +00001377 if(node->isBranch() && !node->hasPredecessors())
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001378 FinalNodeOrder.push_back(node);
1379 else
1380 ccSet.insert(node);
Tanya Lattner260652a2004-10-30 00:39:07 +00001381 }
1382 else
1383 return;
1384
1385 //Loop over successors and recurse if we have not seen this node before
1386 for(MSchedGraphNode::succ_iterator node_succ = node->succ_begin(), end=node->succ_end(); node_succ != end; ++node_succ) {
1387 connectedComponentSet(*node_succ, ccSet, lastNodes);
1388 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001389
Tanya Lattner260652a2004-10-30 00:39:07 +00001390}
1391
1392void ModuloSchedulingPass::predIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001393
1394 for(unsigned j=0; j < FinalNodeOrder.size(); ++j) {
1395 for(MSchedGraphNode::pred_iterator P = FinalNodeOrder[j]->pred_begin(),
1396 E = FinalNodeOrder[j]->pred_end(); P != E; ++P) {
1397
1398 //Check if we are supposed to ignore this edge or not
1399 if(ignoreEdge(*P,FinalNodeOrder[j]))
1400 continue;
1401
Tanya Lattner260652a2004-10-30 00:39:07 +00001402 if(CurrentSet.count(*P))
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001403 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end())
Tanya Lattner260652a2004-10-30 00:39:07 +00001404 IntersectResult.insert(*P);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001405 }
1406 }
1407}
1408
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001409
Tanya Lattner260652a2004-10-30 00:39:07 +00001410
1411
1412
1413void ModuloSchedulingPass::succIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult) {
1414
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001415 for(unsigned j=0; j < FinalNodeOrder.size(); ++j) {
1416 for(MSchedGraphNode::succ_iterator P = FinalNodeOrder[j]->succ_begin(),
1417 E = FinalNodeOrder[j]->succ_end(); P != E; ++P) {
1418
1419 //Check if we are supposed to ignore this edge or not
1420 if(ignoreEdge(FinalNodeOrder[j],*P))
1421 continue;
1422
Tanya Lattner260652a2004-10-30 00:39:07 +00001423 if(CurrentSet.count(*P))
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001424 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end())
Tanya Lattner260652a2004-10-30 00:39:07 +00001425 IntersectResult.insert(*P);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001426 }
1427 }
1428}
1429
Tanya Lattner260652a2004-10-30 00:39:07 +00001430void dumpIntersection(std::set<MSchedGraphNode*> &IntersectCurrent) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001431 std::cerr << "Intersection (";
Tanya Lattner260652a2004-10-30 00:39:07 +00001432 for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(), E = IntersectCurrent.end(); I != E; ++I)
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001433 std::cerr << **I << ", ";
1434 std::cerr << ")\n";
1435}
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001436
1437
1438
1439void ModuloSchedulingPass::orderNodes() {
1440
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001441 TIME_REGION(X, "orderNodes");
1442
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001443 int BOTTOM_UP = 0;
1444 int TOP_DOWN = 1;
1445
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001446 //Set default order
1447 int order = BOTTOM_UP;
1448
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001449
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001450 //Loop over all the sets and place them in the final node order
Tanya Lattner260652a2004-10-30 00:39:07 +00001451 for(std::vector<std::set<MSchedGraphNode*> >::iterator CurrentSet = partialOrder.begin(), E= partialOrder.end(); CurrentSet != E; ++CurrentSet) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001452
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001453 DEBUG(std::cerr << "Processing set in S\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001454 DEBUG(dumpIntersection(*CurrentSet));
1455
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001456 //Result of intersection
Tanya Lattner260652a2004-10-30 00:39:07 +00001457 std::set<MSchedGraphNode*> IntersectCurrent;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001458
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001459 predIntersect(*CurrentSet, IntersectCurrent);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001460
1461 //If the intersection of predecessor and current set is not empty
1462 //sort nodes bottom up
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001463 if(IntersectCurrent.size() != 0) {
1464 DEBUG(std::cerr << "Final Node Order Predecessors and Current Set interesection is NOT empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001465 order = BOTTOM_UP;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001466 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001467 //If empty, use successors
1468 else {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001469 DEBUG(std::cerr << "Final Node Order Predecessors and Current Set interesection is empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001470
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001471 succIntersect(*CurrentSet, IntersectCurrent);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001472
1473 //sort top-down
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001474 if(IntersectCurrent.size() != 0) {
1475 DEBUG(std::cerr << "Final Node Order Successors and Current Set interesection is NOT empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001476 order = TOP_DOWN;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001477 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001478 else {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001479 DEBUG(std::cerr << "Final Node Order Successors and Current Set interesection is empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001480 //Find node with max ASAP in current Set
1481 MSchedGraphNode *node;
1482 int maxASAP = 0;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001483 DEBUG(std::cerr << "Using current set of size " << CurrentSet->size() << "to find max ASAP\n");
Tanya Lattner260652a2004-10-30 00:39:07 +00001484 for(std::set<MSchedGraphNode*>::iterator J = CurrentSet->begin(), JE = CurrentSet->end(); J != JE; ++J) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001485 //Get node attributes
Tanya Lattner260652a2004-10-30 00:39:07 +00001486 MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*J)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001487 //assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!");
Tanya Lattner260652a2004-10-30 00:39:07 +00001488
1489 if(maxASAP <= nodeAttr.ASAP) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001490 maxASAP = nodeAttr.ASAP;
Tanya Lattner260652a2004-10-30 00:39:07 +00001491 node = *J;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001492 }
1493 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001494 assert(node != 0 && "In node ordering node should not be null");
Tanya Lattner260652a2004-10-30 00:39:07 +00001495 IntersectCurrent.insert(node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001496 order = BOTTOM_UP;
1497 }
1498 }
1499
1500 //Repeat until all nodes are put into the final order from current set
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001501 while(IntersectCurrent.size() > 0) {
1502
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001503 if(order == TOP_DOWN) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001504 DEBUG(std::cerr << "Order is TOP DOWN\n");
1505
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001506 while(IntersectCurrent.size() > 0) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001507 DEBUG(std::cerr << "Intersection is not empty, so find heighest height\n");
1508
1509 int MOB = 0;
1510 int height = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001511 MSchedGraphNode *highestHeightNode = *(IntersectCurrent.begin());
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001512
1513 //Find node in intersection with highest heigh and lowest MOB
Tanya Lattner260652a2004-10-30 00:39:07 +00001514 for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(),
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001515 E = IntersectCurrent.end(); I != E; ++I) {
1516
1517 //Get current nodes properties
1518 MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001519
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001520 if(height < nodeAttr.height) {
1521 highestHeightNode = *I;
1522 height = nodeAttr.height;
1523 MOB = nodeAttr.MOB;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001524 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001525 else if(height == nodeAttr.height) {
1526 if(MOB > nodeAttr.height) {
1527 highestHeightNode = *I;
1528 height = nodeAttr.height;
1529 MOB = nodeAttr.MOB;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001530 }
1531 }
1532 }
1533
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001534 //Append our node with greatest height to the NodeOrder
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001535 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestHeightNode) == FinalNodeOrder.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001536 DEBUG(std::cerr << "Adding node to Final Order: " << *highestHeightNode << "\n");
1537 FinalNodeOrder.push_back(highestHeightNode);
1538 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001539
1540 //Remove V from IntersectOrder
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001541 IntersectCurrent.erase(std::find(IntersectCurrent.begin(),
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001542 IntersectCurrent.end(), highestHeightNode));
1543
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001544
1545 //Intersect V's successors with CurrentSet
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001546 for(MSchedGraphNode::succ_iterator P = highestHeightNode->succ_begin(),
1547 E = highestHeightNode->succ_end(); P != E; ++P) {
1548 //if(lower_bound(CurrentSet->begin(),
1549 // CurrentSet->end(), *P) != CurrentSet->end()) {
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001550 if(std::find(CurrentSet->begin(), CurrentSet->end(), *P) != CurrentSet->end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001551 if(ignoreEdge(highestHeightNode, *P))
1552 continue;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001553 //If not already in Intersect, add
Tanya Lattner260652a2004-10-30 00:39:07 +00001554 if(!IntersectCurrent.count(*P))
1555 IntersectCurrent.insert(*P);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001556 }
1557 }
1558 } //End while loop over Intersect Size
1559
1560 //Change direction
1561 order = BOTTOM_UP;
1562
1563 //Reset Intersect to reflect changes in OrderNodes
1564 IntersectCurrent.clear();
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001565 predIntersect(*CurrentSet, IntersectCurrent);
1566
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001567 } //End If TOP_DOWN
1568
1569 //Begin if BOTTOM_UP
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001570 else {
1571 DEBUG(std::cerr << "Order is BOTTOM UP\n");
1572 while(IntersectCurrent.size() > 0) {
1573 DEBUG(std::cerr << "Intersection of size " << IntersectCurrent.size() << ", finding highest depth\n");
1574
1575 //dump intersection
1576 DEBUG(dumpIntersection(IntersectCurrent));
1577 //Get node with highest depth, if a tie, use one with lowest
1578 //MOB
1579 int MOB = 0;
1580 int depth = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001581 MSchedGraphNode *highestDepthNode = *(IntersectCurrent.begin());
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001582
Tanya Lattner260652a2004-10-30 00:39:07 +00001583 for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(),
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001584 E = IntersectCurrent.end(); I != E; ++I) {
1585 //Find node attribute in graph
1586 MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001587
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001588 if(depth < nodeAttr.depth) {
1589 highestDepthNode = *I;
1590 depth = nodeAttr.depth;
1591 MOB = nodeAttr.MOB;
1592 }
1593 else if(depth == nodeAttr.depth) {
1594 if(MOB > nodeAttr.MOB) {
1595 highestDepthNode = *I;
1596 depth = nodeAttr.depth;
1597 MOB = nodeAttr.MOB;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001598 }
1599 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001600 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001601
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001602
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001603
1604 //Append highest depth node to the NodeOrder
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001605 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestDepthNode) == FinalNodeOrder.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001606 DEBUG(std::cerr << "Adding node to Final Order: " << *highestDepthNode << "\n");
1607 FinalNodeOrder.push_back(highestDepthNode);
1608 }
1609 //Remove heightestDepthNode from IntersectOrder
Tanya Lattner260652a2004-10-30 00:39:07 +00001610 IntersectCurrent.erase(highestDepthNode);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001611
1612
1613 //Intersect heightDepthNode's pred with CurrentSet
1614 for(MSchedGraphNode::pred_iterator P = highestDepthNode->pred_begin(),
1615 E = highestDepthNode->pred_end(); P != E; ++P) {
Tanya Lattner260652a2004-10-30 00:39:07 +00001616 if(CurrentSet->count(*P)) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001617 if(ignoreEdge(*P, highestDepthNode))
1618 continue;
1619
1620 //If not already in Intersect, add
Tanya Lattner260652a2004-10-30 00:39:07 +00001621 if(!IntersectCurrent.count(*P))
1622 IntersectCurrent.insert(*P);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001623 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001624 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001625
1626 } //End while loop over Intersect Size
1627
1628 //Change order
1629 order = TOP_DOWN;
1630
1631 //Reset IntersectCurrent to reflect changes in OrderNodes
1632 IntersectCurrent.clear();
1633 succIntersect(*CurrentSet, IntersectCurrent);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001634 } //End if BOTTOM_DOWN
1635
Tanya Lattner420025b2004-10-10 22:44:35 +00001636 DEBUG(std::cerr << "Current Intersection Size: " << IntersectCurrent.size() << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001637 }
1638 //End Wrapping while loop
Tanya Lattner420025b2004-10-10 22:44:35 +00001639 DEBUG(std::cerr << "Ending Size of Current Set: " << CurrentSet->size() << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001640 }//End for over all sets of nodes
Tanya Lattner420025b2004-10-10 22:44:35 +00001641
1642 //FIXME: As the algorithm stands it will NEVER add an instruction such as ba (with no
1643 //data dependencies) to the final order. We add this manually. It will always be
1644 //in the last set of S since its not part of a recurrence
1645 //Loop over all the sets and place them in the final node order
Tanya Lattner260652a2004-10-30 00:39:07 +00001646 std::vector<std::set<MSchedGraphNode*> > ::reverse_iterator LastSet = partialOrder.rbegin();
1647 for(std::set<MSchedGraphNode*>::iterator CurrentNode = LastSet->begin(), LastNode = LastSet->end();
Tanya Lattner420025b2004-10-10 22:44:35 +00001648 CurrentNode != LastNode; ++CurrentNode) {
1649 if((*CurrentNode)->getInst()->getOpcode() == V9::BA)
1650 FinalNodeOrder.push_back(*CurrentNode);
1651 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001652 //Return final Order
1653 //return FinalNodeOrder;
1654}
1655
Tanya Lattner9532ab92005-03-23 01:47:20 +00001656bool ModuloSchedulingPass::computeSchedule(const MachineBasicBlock *BB) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001657
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001658 TIME_REGION(X, "computeSchedule");
1659
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001660 bool success = false;
1661
Tanya Lattner260652a2004-10-30 00:39:07 +00001662 //FIXME: Should be set to max II of the original loop
1663 //Cap II in order to prevent infinite loop
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001664 int capII = 100;
Tanya Lattner260652a2004-10-30 00:39:07 +00001665
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001666 while(!success) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001667
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001668 //Keep track of branches, but do not insert into the schedule
1669 std::vector<MSchedGraphNode*> branches;
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001670
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001671 //Loop over the final node order and process each node
1672 for(std::vector<MSchedGraphNode*>::iterator I = FinalNodeOrder.begin(),
1673 E = FinalNodeOrder.end(); I != E; ++I) {
1674
1675 //CalculateEarly and Late start
1676 int EarlyStart = -1;
1677 int LateStart = 99999; //Set to something higher then we would ever expect (FIXME)
1678 bool hasSucc = false;
1679 bool hasPred = false;
Tanya Lattner9532ab92005-03-23 01:47:20 +00001680 bool sched;
1681
1682 if((*I)->isBranch())
1683 if((*I)->hasPredecessors())
1684 sched = true;
1685 else
1686 sched = false;
1687 else
1688 sched = true;
1689
1690 if(sched) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00001691 //Loop over nodes in the schedule and determine if they are predecessors
1692 //or successors of the node we are trying to schedule
1693 for(MSSchedule::schedule_iterator nodesByCycle = schedule.begin(), nodesByCycleEnd = schedule.end();
1694 nodesByCycle != nodesByCycleEnd; ++nodesByCycle) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001695
Tanya Lattner4cffb582004-05-26 06:27:18 +00001696 //For this cycle, get the vector of nodes schedule and loop over it
1697 for(std::vector<MSchedGraphNode*>::iterator schedNode = nodesByCycle->second.begin(), SNE = nodesByCycle->second.end(); schedNode != SNE; ++schedNode) {
1698
1699 if((*I)->isPredecessor(*schedNode)) {
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001700 int diff = (*I)->getInEdge(*schedNode).getIteDiff();
1701 int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II;
1702 DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n");
1703 DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n");
1704 EarlyStart = std::max(EarlyStart, ES_Temp);
1705 hasPred = true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001706 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001707 if((*I)->isSuccessor(*schedNode)) {
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001708 int diff = (*schedNode)->getInEdge(*I).getIteDiff();
1709 int LS_Temp = nodesByCycle->first - (*I)->getLatency() + diff * II;
1710 DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n");
1711 DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n");
1712 LateStart = std::min(LateStart, LS_Temp);
1713 hasSucc = true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001714 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001715 }
1716 }
1717 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001718 else {
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001719 branches.push_back(*I);
1720 continue;
1721 }
1722
1723 //Check if this node is a pred or succ to a branch, and restrict its placement
1724 //even though the branch is not in the schedule
1725 int count = branches.size();
1726 for(std::vector<MSchedGraphNode*>::iterator B = branches.begin(), BE = branches.end();
1727 B != BE; ++B) {
1728 if((*I)->isPredecessor(*B)) {
1729 int diff = (*I)->getInEdge(*B).getIteDiff();
Tanya Lattner9532ab92005-03-23 01:47:20 +00001730 int ES_Temp = (II+count-1) + (*B)->getLatency() - diff * II;
1731 DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << (II+count)-1 << "\n");
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001732 DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n");
1733 EarlyStart = std::max(EarlyStart, ES_Temp);
1734 hasPred = true;
Tanya Lattner420025b2004-10-10 22:44:35 +00001735 }
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001736
1737 if((*I)->isSuccessor(*B)) {
1738 int diff = (*B)->getInEdge(*I).getIteDiff();
Tanya Lattner9532ab92005-03-23 01:47:20 +00001739 int LS_Temp = (II+count-1) - (*I)->getLatency() + diff * II;
1740 DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << (II+count-1) << "\n");
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001741 DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n");
1742 LateStart = std::min(LateStart, LS_Temp);
1743 hasSucc = true;
Tanya Lattner420025b2004-10-10 22:44:35 +00001744 }
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001745
1746 count--;
Tanya Lattner4cffb582004-05-26 06:27:18 +00001747 }
1748
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001749 //Check if the node has no pred or successors and set Early Start to its ASAP
1750 if(!hasSucc && !hasPred)
1751 EarlyStart = nodeToAttributesMap.find(*I)->second.ASAP;
1752
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001753 DEBUG(std::cerr << "Has Successors: " << hasSucc << ", Has Pred: " << hasPred << "\n");
1754 DEBUG(std::cerr << "EarlyStart: " << EarlyStart << ", LateStart: " << LateStart << "\n");
1755
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001756 //Now, try to schedule this node depending upon its pred and successor in the schedule
1757 //already
1758 if(!hasSucc && hasPred)
1759 success = scheduleNode(*I, EarlyStart, (EarlyStart + II -1));
1760 else if(!hasPred && hasSucc)
1761 success = scheduleNode(*I, LateStart, (LateStart - II +1));
Tanya Lattner01114742005-01-18 04:15:41 +00001762 else if(hasPred && hasSucc) {
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001763 if(EarlyStart > LateStart) {
Tanya Lattner9532ab92005-03-23 01:47:20 +00001764 success = false;
1765 //LateStart = EarlyStart;
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001766 DEBUG(std::cerr << "Early Start can not be later then the late start cycle, schedule fails\n");
1767 }
Tanya Lattner9532ab92005-03-23 01:47:20 +00001768 else
1769 success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1)));
Tanya Lattner01114742005-01-18 04:15:41 +00001770 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001771 else
1772 success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1);
1773
1774 if(!success) {
Tanya Lattnere1df2122004-11-22 20:41:24 +00001775 ++IncreasedII;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001776 ++II;
1777 schedule.clear();
1778 break;
1779 }
1780
1781 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001782
Tanya Lattner260652a2004-10-30 00:39:07 +00001783 if(success) {
1784 DEBUG(std::cerr << "Constructing Schedule Kernel\n");
Tanya Lattner9532ab92005-03-23 01:47:20 +00001785 success = schedule.constructKernel(II, branches, indVarInstrs[BB]);
Tanya Lattner260652a2004-10-30 00:39:07 +00001786 DEBUG(std::cerr << "Done Constructing Schedule Kernel\n");
1787 if(!success) {
Tanya Lattnere1df2122004-11-22 20:41:24 +00001788 ++IncreasedII;
Tanya Lattner260652a2004-10-30 00:39:07 +00001789 ++II;
1790 schedule.clear();
1791 }
Tanya Lattner9532ab92005-03-23 01:47:20 +00001792 DEBUG(std::cerr << "Final II: " << II << "\n");
Tanya Lattner4cffb582004-05-26 06:27:18 +00001793 }
Tanya Lattner260652a2004-10-30 00:39:07 +00001794
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001795 if(II >= capII) {
1796 DEBUG(std::cerr << "Maximum II reached, giving up\n");
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001797 return false;
Tanya Lattner01b4abd2005-02-23 02:01:42 +00001798 }
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001799
Tanya Lattner260652a2004-10-30 00:39:07 +00001800 assert(II < capII && "The II should not exceed the original loop number of cycles");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001801 }
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001802 return true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001803}
1804
1805
1806bool ModuloSchedulingPass::scheduleNode(MSchedGraphNode *node,
1807 int start, int end) {
1808 bool success = false;
1809
1810 DEBUG(std::cerr << *node << " (Start Cycle: " << start << ", End Cycle: " << end << ")\n");
1811
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001812 //Make sure start and end are not negative
Tanya Lattner9532ab92005-03-23 01:47:20 +00001813 //if(start < 0) {
1814 //start = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001815
Tanya Lattner9532ab92005-03-23 01:47:20 +00001816 //}
1817 //if(end < 0)
1818 //end = 0;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001819
1820 bool forward = true;
1821 if(start > end)
1822 forward = false;
1823
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001824 bool increaseSC = true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001825 int cycle = start ;
1826
1827
1828 while(increaseSC) {
1829
1830 increaseSC = false;
1831
Tanya Lattner4cffb582004-05-26 06:27:18 +00001832 increaseSC = schedule.insert(node, cycle);
1833
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001834 if(!increaseSC)
1835 return true;
1836
1837 //Increment cycle to try again
1838 if(forward) {
1839 ++cycle;
1840 DEBUG(std::cerr << "Increase cycle: " << cycle << "\n");
1841 if(cycle > end)
1842 return false;
1843 }
1844 else {
1845 --cycle;
1846 DEBUG(std::cerr << "Decrease cycle: " << cycle << "\n");
1847 if(cycle < end)
1848 return false;
1849 }
1850 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001851
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001852 return success;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001853}
Tanya Lattner4cffb582004-05-26 06:27:18 +00001854
Tanya Lattner9532ab92005-03-23 01:47:20 +00001855void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00001856
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001857 //Keep a map to easily know whats in the kernel
Tanya Lattner4cffb582004-05-26 06:27:18 +00001858 std::map<int, std::set<const MachineInstr*> > inKernel;
1859 int maxStageCount = 0;
1860
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001861 //Keep a map of new values we consumed in case they need to be added back
1862 std::map<Value*, std::map<int, Value*> > consumedValues;
1863
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001864 MSchedGraphNode *branch = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001865 MSchedGraphNode *BAbranch = 0;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001866
Tanya Lattnere1df2122004-11-22 20:41:24 +00001867 schedule.print(std::cerr);
1868
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001869 std::vector<MSchedGraphNode*> branches;
1870
Tanya Lattner4cffb582004-05-26 06:27:18 +00001871 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
1872 maxStageCount = std::max(maxStageCount, I->second);
1873
Tanya Lattner4cffb582004-05-26 06:27:18 +00001874 //Put int the map so we know what instructions in each stage are in the kernel
Tanya Lattner9532ab92005-03-23 01:47:20 +00001875 DEBUG(std::cerr << "Inserting instruction " << *(I->first) << " into map at stage " << I->second << "\n");
1876 inKernel[I->second].insert(I->first);
Tanya Lattner4cffb582004-05-26 06:27:18 +00001877 }
1878
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001879 //Get target information to look at machine operands
1880 const TargetInstrInfo *mii = target.getInstrInfo();
1881
1882 //Now write the prologues
1883 for(int i = 0; i < maxStageCount; ++i) {
1884 BasicBlock *llvmBB = new BasicBlock("PROLOGUE", (Function*) (origBB->getBasicBlock()->getParent()));
Tanya Lattner4cffb582004-05-26 06:27:18 +00001885 MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB);
1886
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001887 DEBUG(std::cerr << "i=" << i << "\n");
Tanya Lattner9532ab92005-03-23 01:47:20 +00001888 for(int j = i; j >= 0; --j) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001889 for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
1890 if(inKernel[j].count(&*MI)) {
Tanya Lattner420025b2004-10-10 22:44:35 +00001891 MachineInstr *instClone = MI->clone();
1892 machineBB->push_back(instClone);
Tanya Lattner9532ab92005-03-23 01:47:20 +00001893
1894 //If its a branch, insert a nop
1895 if(mii->isBranch(instClone->getOpcode()))
1896 BuildMI(machineBB, V9::NOP, 0);
1897
1898
Tanya Lattner420025b2004-10-10 22:44:35 +00001899 DEBUG(std::cerr << "Cloning: " << *MI << "\n");
1900
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001901 //After cloning, we may need to save the value that this instruction defines
1902 for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) {
Tanya Lattner9532ab92005-03-23 01:47:20 +00001903 Instruction *tmp;
1904
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001905 //get machine operand
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001906 MachineOperand &mOp = instClone->getOperand(opNum);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001907 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
1908
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001909 //Check if this is a value we should save
1910 if(valuesToSave.count(mOp.getVRegValue())) {
1911 //Save copy in tmpInstruction
1912 tmp = new TmpInstruction(mOp.getVRegValue());
1913
Tanya Lattner80f08552004-11-02 21:04:56 +00001914 //Add TmpInstruction to safe LLVM Instruction MCFI
1915 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00001916 tempMvec.addTemp((Value*) tmp);
1917
Tanya Lattner420025b2004-10-10 22:44:35 +00001918 DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n");
1919
1920 newValues[mOp.getVRegValue()][i]= tmp;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001921 newValLocation[tmp] = machineBB;
1922
Tanya Lattner420025b2004-10-10 22:44:35 +00001923 DEBUG(std::cerr << "Machine Instr Operands: " << *(mOp.getVRegValue()) << ", 0, " << *tmp << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001924
1925 //Create machine instruction and put int machineBB
Tanya Lattner9532ab92005-03-23 01:47:20 +00001926 MachineInstr *saveValue;
1927 if(mOp.getVRegValue()->getType() == Type::FloatTy)
1928 saveValue = BuildMI(machineBB, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
1929 else if(mOp.getVRegValue()->getType() == Type::DoubleTy)
1930 saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
1931 else
1932 saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
1933
1934
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001935 DEBUG(std::cerr << "Created new machine instr: " << *saveValue << "\n");
1936 }
1937 }
Tanya Lattner420025b2004-10-10 22:44:35 +00001938
1939 //We may also need to update the value that we use if its from an earlier prologue
1940 if(j != 0) {
1941 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001942 if(newValues.count(mOp.getVRegValue())) {
1943 if(newValues[mOp.getVRegValue()].count(i-1)) {
1944 Value *oldV = mOp.getVRegValue();
Tanya Lattner420025b2004-10-10 22:44:35 +00001945 DEBUG(std::cerr << "Replaced this value: " << mOp.getVRegValue() << " With:" << (newValues[mOp.getVRegValue()][i-1]) << "\n");
1946 //Update the operand with the right value
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001947 mOp.setValueReg(newValues[mOp.getVRegValue()][i-1]);
1948
1949 //Remove this value since we have consumed it
1950 //NOTE: Should this only be done if j != maxStage?
1951 consumedValues[oldV][i-1] = (newValues[oldV][i-1]);
1952 DEBUG(std::cerr << "Deleted value: " << consumedValues[oldV][i-1] << "\n");
1953 newValues[oldV].erase(i-1);
Tanya Lattner420025b2004-10-10 22:44:35 +00001954 }
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001955 }
1956 else
1957 if(consumedValues.count(mOp.getVRegValue()))
1958 assert(!consumedValues[mOp.getVRegValue()].count(i-1) && "Found a case where we need the value");
Tanya Lattner420025b2004-10-10 22:44:35 +00001959 }
1960 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001961 }
1962 }
Tanya Lattner20890832004-05-28 20:14:12 +00001963 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001964 }
1965
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001966
Tanya Lattner9532ab92005-03-23 01:47:20 +00001967 /*for(std::vector<MSchedGraphNode*>::iterator BR = branches.begin(), BE = branches.end(); BR != BE; ++BR) {
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001968
1969 //Stick in branch at the end
1970 machineBB->push_back((*BR)->getInst()->clone());
Tanya Lattner260652a2004-10-30 00:39:07 +00001971
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001972 //Add nop
1973 BuildMI(machineBB, V9::NOP, 0);
Tanya Lattner9532ab92005-03-23 01:47:20 +00001974 }*/
Tanya Lattner260652a2004-10-30 00:39:07 +00001975
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001976
1977 (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
Tanya Lattner4cffb582004-05-26 06:27:18 +00001978 prologues.push_back(machineBB);
1979 llvm_prologues.push_back(llvmBB);
1980 }
1981}
1982
Tanya Lattner9532ab92005-03-23 01:47:20 +00001983void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues,std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs ) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001984
Tanya Lattner20890832004-05-28 20:14:12 +00001985 std::map<int, std::set<const MachineInstr*> > inKernel;
Tanya Lattner420025b2004-10-10 22:44:35 +00001986
Tanya Lattner20890832004-05-28 20:14:12 +00001987 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
Tanya Lattner20890832004-05-28 20:14:12 +00001988
1989 //Ignore the branch, we will handle this separately
Tanya Lattner9532ab92005-03-23 01:47:20 +00001990 //if(I->first->isBranch())
1991 //continue;
Tanya Lattner20890832004-05-28 20:14:12 +00001992
1993 //Put int the map so we know what instructions in each stage are in the kernel
Tanya Lattner9532ab92005-03-23 01:47:20 +00001994 inKernel[I->second].insert(I->first);
Tanya Lattner20890832004-05-28 20:14:12 +00001995 }
1996
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001997 std::map<Value*, Value*> valPHIs;
1998
Tanya Lattner420025b2004-10-10 22:44:35 +00001999 //some debug stuff, will remove later
2000 DEBUG(for(std::map<Value*, std::map<int, Value*> >::iterator V = newValues.begin(), E = newValues.end(); V !=E; ++V) {
2001 std::cerr << "Old Value: " << *(V->first) << "\n";
2002 for(std::map<int, Value*>::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I)
2003 std::cerr << "Stage: " << I->first << " Value: " << *(I->second) << "\n";
2004 });
2005
2006 //some debug stuff, will remove later
2007 DEBUG(for(std::map<Value*, std::map<int, Value*> >::iterator V = kernelPHIs.begin(), E = kernelPHIs.end(); V !=E; ++V) {
2008 std::cerr << "Old Value: " << *(V->first) << "\n";
2009 for(std::map<int, Value*>::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I)
2010 std::cerr << "Stage: " << I->first << " Value: " << *(I->second) << "\n";
2011 });
2012
Tanya Lattner20890832004-05-28 20:14:12 +00002013 //Now write the epilogues
Tanya Lattner420025b2004-10-10 22:44:35 +00002014 for(int i = schedule.getMaxStage()-1; i >= 0; --i) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002015 BasicBlock *llvmBB = new BasicBlock("EPILOGUE", (Function*) (origBB->getBasicBlock()->getParent()));
Tanya Lattner20890832004-05-28 20:14:12 +00002016 MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002017
Tanya Lattner420025b2004-10-10 22:44:35 +00002018 DEBUG(std::cerr << " Epilogue #: " << i << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002019
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002020
Tanya Lattnera6457502004-10-14 06:04:28 +00002021 std::map<Value*, int> inEpilogue;
Tanya Lattner420025b2004-10-10 22:44:35 +00002022
2023 for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
2024 for(int j=schedule.getMaxStage(); j > i; --j) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002025 if(inKernel[j].count(&*MI)) {
2026 DEBUG(std::cerr << "Cloning instruction " << *MI << "\n");
2027 MachineInstr *clone = MI->clone();
2028
2029 //Update operands that need to use the result from the phi
Tanya Lattner420025b2004-10-10 22:44:35 +00002030 for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002031 //get machine operand
Tanya Lattner420025b2004-10-10 22:44:35 +00002032 const MachineOperand &mOp = clone->getOperand(opNum);
Tanya Lattner420025b2004-10-10 22:44:35 +00002033
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002034 if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) {
Tanya Lattner420025b2004-10-10 22:44:35 +00002035
Tanya Lattner9532ab92005-03-23 01:47:20 +00002036 DEBUG(std::cerr << "Writing PHI for " << (mOp.getVRegValue()) << "\n");
Tanya Lattnera6457502004-10-14 06:04:28 +00002037
2038 //If this is the last instructions for the max iterations ago, don't update operands
2039 if(inEpilogue.count(mOp.getVRegValue()))
2040 if(inEpilogue[mOp.getVRegValue()] == i)
2041 continue;
Tanya Lattner420025b2004-10-10 22:44:35 +00002042
2043 //Quickly write appropriate phis for this operand
2044 if(newValues.count(mOp.getVRegValue())) {
2045 if(newValues[mOp.getVRegValue()].count(i)) {
2046 Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]);
Tanya Lattnera6457502004-10-14 06:04:28 +00002047
2048 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00002049 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00002050 tempMvec.addTemp((Value*) tmp);
2051
Tanya Lattner9532ab92005-03-23 01:47:20 +00002052 //assert of no kernelPHI for this value
2053 assert(kernelPHIs[mOp.getVRegValue()][i] !=0 && "Must have final kernel phi to construct epilogue phi");
2054
Tanya Lattner420025b2004-10-10 22:44:35 +00002055 MachineInstr *saveValue = BuildMI(machineBB, V9::PHI, 3).addReg(newValues[mOp.getVRegValue()][i]).addReg(kernelPHIs[mOp.getVRegValue()][i]).addRegDef(tmp);
2056 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
2057 valPHIs[mOp.getVRegValue()] = tmp;
2058 }
2059 }
2060
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002061 if(valPHIs.count(mOp.getVRegValue())) {
2062 //Update the operand in the cloned instruction
Tanya Lattner420025b2004-10-10 22:44:35 +00002063 clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002064 }
2065 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002066 else if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef())) {
2067 inEpilogue[mOp.getVRegValue()] = i;
2068 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002069 }
2070 machineBB->push_back(clone);
2071 }
2072 }
Tanya Lattner420025b2004-10-10 22:44:35 +00002073 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002074
Tanya Lattner20890832004-05-28 20:14:12 +00002075 (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
2076 epilogues.push_back(machineBB);
2077 llvm_epilogues.push_back(llvmBB);
Tanya Lattner420025b2004-10-10 22:44:35 +00002078
2079 DEBUG(std::cerr << "EPILOGUE #" << i << "\n");
2080 DEBUG(machineBB->print(std::cerr));
Tanya Lattner20890832004-05-28 20:14:12 +00002081 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002082}
2083
Tanya Lattner9532ab92005-03-23 01:47:20 +00002084void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002085
2086 //Keep track of operands that are read and saved from a previous iteration. The new clone
2087 //instruction will use the result of the phi instead.
2088 std::map<Value*, Value*> finalPHIValue;
2089 std::map<Value*, Value*> kernelValue;
2090
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00002091 //Branches are a special case
2092 std::vector<MachineInstr*> branches;
2093
Tanya Lattner9532ab92005-03-23 01:47:20 +00002094 //Get target information to look at machine operands
2095 const TargetInstrInfo *mii = target.getInstrInfo();
2096
2097 //Create TmpInstructions for the final phis
2098 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002099
Tanya Lattner9532ab92005-03-23 01:47:20 +00002100 DEBUG(std::cerr << "Stage: " << I->second << " Inst: " << *(I->first) << "\n";);
Tanya Lattner420025b2004-10-10 22:44:35 +00002101
Tanya Lattner9532ab92005-03-23 01:47:20 +00002102 /*if(I->first->isBranch()) {
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00002103 //Clone instruction
2104 const MachineInstr *inst = I->first->getInst();
2105 MachineInstr *instClone = inst->clone();
2106 branches.push_back(instClone);
Tanya Lattner01114742005-01-18 04:15:41 +00002107 continue;
Tanya Lattner9532ab92005-03-23 01:47:20 +00002108 }*/
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00002109
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002110 //Clone instruction
Tanya Lattner9532ab92005-03-23 01:47:20 +00002111 const MachineInstr *inst = I->first;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002112 MachineInstr *instClone = inst->clone();
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002113
Tanya Lattner420025b2004-10-10 22:44:35 +00002114 //Insert into machine basic block
2115 machineBB->push_back(instClone);
2116
Tanya Lattner9532ab92005-03-23 01:47:20 +00002117 if(mii->isBranch(instClone->getOpcode()))
2118 BuildMI(machineBB, V9::NOP, 0);
2119
Tanya Lattnerced82222004-11-16 21:31:37 +00002120 DEBUG(std::cerr << "Cloned Inst: " << *instClone << "\n");
2121
Tanya Lattner420025b2004-10-10 22:44:35 +00002122 //Loop over Machine Operands
2123 for(unsigned i=0; i < inst->getNumOperands(); ++i) {
2124 //get machine operand
2125 const MachineOperand &mOp = inst->getOperand(i);
2126
2127 if(I->second != 0) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002128 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
Tanya Lattner420025b2004-10-10 22:44:35 +00002129
2130 //Check to see where this operand is defined if this instruction is from max stage
2131 if(I->second == schedule.getMaxStage()) {
2132 DEBUG(std::cerr << "VREG: " << *(mOp.getVRegValue()) << "\n");
2133 }
2134
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002135 //If its in the value saved, we need to create a temp instruction and use that instead
2136 if(valuesToSave.count(mOp.getVRegValue())) {
Tanya Lattnerced82222004-11-16 21:31:37 +00002137
2138 //Check if we already have a final PHI value for this
2139 if(!finalPHIValue.count(mOp.getVRegValue())) {
2140 TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
2141
2142 //Get machine code for this instruction
2143 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
2144 tempMvec.addTemp((Value*) tmp);
2145
2146 //Update the operand in the cloned instruction
2147 instClone->getOperand(i).setValueReg(tmp);
2148
2149 //save this as our final phi
2150 finalPHIValue[mOp.getVRegValue()] = tmp;
2151 newValLocation[tmp] = machineBB;
2152 }
2153 else {
2154 //Use the previous final phi value
2155 instClone->getOperand(i).setValueReg(finalPHIValue[mOp.getVRegValue()]);
2156 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002157 }
2158 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002159 }
Tanya Lattner420025b2004-10-10 22:44:35 +00002160 if(I->second != schedule.getMaxStage()) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002161 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
2162 if(valuesToSave.count(mOp.getVRegValue())) {
2163
2164 TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
2165
Tanya Lattnera6457502004-10-14 06:04:28 +00002166 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00002167 MachineCodeForInstruction & tempVec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00002168 tempVec.addTemp((Value*) tmp);
2169
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002170 //Create new machine instr and put in MBB
Tanya Lattner9532ab92005-03-23 01:47:20 +00002171 MachineInstr *saveValue;
2172 if(mOp.getVRegValue()->getType() == Type::FloatTy)
2173 saveValue = BuildMI(machineBB, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
2174 else if(mOp.getVRegValue()->getType() == Type::DoubleTy)
2175 saveValue = BuildMI(machineBB, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
2176 else
2177 saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
2178
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002179
2180 //Save for future cleanup
2181 kernelValue[mOp.getVRegValue()] = tmp;
2182 newValLocation[tmp] = machineBB;
Tanya Lattner420025b2004-10-10 22:44:35 +00002183 kernelPHIs[mOp.getVRegValue()][schedule.getMaxStage()-1] = tmp;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002184 }
2185 }
2186 }
2187 }
Tanya Lattner420025b2004-10-10 22:44:35 +00002188
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002189 }
2190
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00002191 //Add branches
2192 for(std::vector<MachineInstr*>::iterator I = branches.begin(), E = branches.end(); I != E; ++I) {
2193 machineBB->push_back(*I);
2194 BuildMI(machineBB, V9::NOP, 0);
2195 }
2196
2197
Tanya Lattner420025b2004-10-10 22:44:35 +00002198 DEBUG(std::cerr << "KERNEL before PHIs\n");
2199 DEBUG(machineBB->print(std::cerr));
2200
2201
2202 //Loop over each value we need to generate phis for
2203 for(std::map<Value*, std::map<int, Value*> >::iterator V = newValues.begin(),
2204 E = newValues.end(); V != E; ++V) {
2205
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002206
2207 DEBUG(std::cerr << "Writing phi for" << *(V->first));
Tanya Lattner420025b2004-10-10 22:44:35 +00002208 DEBUG(std::cerr << "\nMap of Value* for this phi\n");
2209 DEBUG(for(std::map<int, Value*>::iterator I = V->second.begin(),
2210 IE = V->second.end(); I != IE; ++I) {
2211 std::cerr << "Stage: " << I->first;
2212 std::cerr << " Value: " << *(I->second) << "\n";
2213 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002214
Tanya Lattner420025b2004-10-10 22:44:35 +00002215 //If we only have one current iteration live, its safe to set lastPhi = to kernel value
2216 if(V->second.size() == 1) {
2217 assert(kernelValue[V->first] != 0 && "Kernel value* must exist to create phi");
2218 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(),V9::PHI, 3).addReg(V->second.begin()->second).addReg(kernelValue[V->first]).addRegDef(finalPHIValue[V->first]);
Tanya Lattner9532ab92005-03-23 01:47:20 +00002219 DEBUG(std::cerr << "Resulting PHI (one live): " << *saveValue << "\n");
2220 kernelPHIs[V->first][V->second.begin()->first] = kernelValue[V->first];
2221 DEBUG(std::cerr << "Put kernel phi in at stage: " << schedule.getMaxStage()-1 << " (map stage = " << V->second.begin()->first << ")\n");
2222 }
Tanya Lattner420025b2004-10-10 22:44:35 +00002223 else {
2224
2225 //Keep track of last phi created.
2226 Instruction *lastPhi = 0;
2227
2228 unsigned count = 1;
2229 //Loop over the the map backwards to generate phis
2230 for(std::map<int, Value*>::reverse_iterator I = V->second.rbegin(), IE = V->second.rend();
2231 I != IE; ++I) {
2232
2233 if(count < (V->second).size()) {
2234 if(lastPhi == 0) {
2235 lastPhi = new TmpInstruction(I->second);
Tanya Lattnera6457502004-10-14 06:04:28 +00002236
2237 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00002238 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00002239 tempMvec.addTemp((Value*) lastPhi);
2240
Tanya Lattner420025b2004-10-10 22:44:35 +00002241 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(kernelValue[V->first]).addReg(I->second).addRegDef(lastPhi);
2242 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
2243 newValLocation[lastPhi] = machineBB;
2244 }
2245 else {
2246 Instruction *tmp = new TmpInstruction(I->second);
Tanya Lattnera6457502004-10-14 06:04:28 +00002247
2248 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00002249 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00002250 tempMvec.addTemp((Value*) tmp);
2251
2252
Tanya Lattner420025b2004-10-10 22:44:35 +00002253 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp);
2254 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
2255 lastPhi = tmp;
2256 kernelPHIs[V->first][I->first] = lastPhi;
2257 newValLocation[lastPhi] = machineBB;
2258 }
2259 }
2260 //Final phi value
2261 else {
2262 //The resulting value must be the Value* we created earlier
2263 assert(lastPhi != 0 && "Last phi is NULL!\n");
2264 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(finalPHIValue[V->first]);
2265 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
2266 kernelPHIs[V->first][I->first] = finalPHIValue[V->first];
2267 }
2268
2269 ++count;
2270 }
2271
2272 }
2273 }
2274
2275 DEBUG(std::cerr << "KERNEL after PHIs\n");
2276 DEBUG(machineBB->print(std::cerr));
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002277}
2278
Tanya Lattner420025b2004-10-10 22:44:35 +00002279
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002280void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vector<MachineBasicBlock *> &prologues, std::vector<MachineBasicBlock *> &epilogues, MachineBasicBlock *kernelBB, std::map<Value*, MachineBasicBlock*> &newValLocation) {
2281
2282 //Worklist to delete things
2283 std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> > worklist;
Tanya Lattnera6457502004-10-14 06:04:28 +00002284
2285 //Worklist of TmpInstructions that need to be added to a MCFI
2286 std::vector<Instruction*> addToMCFI;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002287
Tanya Lattnera6457502004-10-14 06:04:28 +00002288 //Worklist to add OR instructions to end of kernel so not to invalidate the iterator
2289 //std::vector<std::pair<Instruction*, Value*> > newORs;
2290
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002291 const TargetInstrInfo *TMI = target.getInstrInfo();
2292
2293 //Start with the kernel and for each phi insert a copy for the phi def and for each arg
2294 for(MachineBasicBlock::iterator I = kernelBB->begin(), E = kernelBB->end(); I != E; ++I) {
Tanya Lattnera6457502004-10-14 06:04:28 +00002295
Tanya Lattner80f08552004-11-02 21:04:56 +00002296 DEBUG(std::cerr << "Looking at Instr: " << *I << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002297 //Get op code and check if its a phi
Tanya Lattnera6457502004-10-14 06:04:28 +00002298 if(I->getOpcode() == V9::PHI) {
2299
2300 DEBUG(std::cerr << "Replacing PHI: " << *I << "\n");
2301 Instruction *tmp = 0;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002302
Tanya Lattnera6457502004-10-14 06:04:28 +00002303 for(unsigned i = 0; i < I->getNumOperands(); ++i) {
2304 //Get Operand
2305 const MachineOperand &mOp = I->getOperand(i);
2306 assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
2307
2308 if(!tmp) {
2309 tmp = new TmpInstruction(mOp.getVRegValue());
2310 addToMCFI.push_back(tmp);
2311 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002312
Tanya Lattnera6457502004-10-14 06:04:28 +00002313 //Now for all our arguments we read, OR to the new TmpInstruction that we created
2314 if(mOp.isUse()) {
2315 DEBUG(std::cerr << "Use: " << mOp << "\n");
2316 //Place a copy at the end of its BB but before the branches
2317 assert(newValLocation.count(mOp.getVRegValue()) && "We must know where this value is located\n");
2318 //Reverse iterate to find the branches, we can safely assume no instructions have been
2319 //put in the nop positions
2320 for(MachineBasicBlock::iterator inst = --(newValLocation[mOp.getVRegValue()])->end(), endBB = (newValLocation[mOp.getVRegValue()])->begin(); inst != endBB; --inst) {
2321 MachineOpCode opc = inst->getOpcode();
2322 if(TMI->isBranch(opc) || TMI->isNop(opc))
2323 continue;
2324 else {
Tanya Lattner9532ab92005-03-23 01:47:20 +00002325 if(mOp.getVRegValue()->getType() == Type::FloatTy)
2326 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
2327 else if(mOp.getVRegValue()->getType() == Type::DoubleTy)
2328 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
2329 else
2330 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
2331
Tanya Lattnera6457502004-10-14 06:04:28 +00002332 break;
2333 }
2334
2335 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002336
Tanya Lattnera6457502004-10-14 06:04:28 +00002337 }
2338 else {
2339 //Remove the phi and replace it with an OR
2340 DEBUG(std::cerr << "Def: " << mOp << "\n");
2341 //newORs.push_back(std::make_pair(tmp, mOp.getVRegValue()));
Tanya Lattner9532ab92005-03-23 01:47:20 +00002342 if(tmp->getType() == Type::FloatTy)
2343 BuildMI(*kernelBB, I, V9::FMOVS, 3).addReg(tmp).addRegDef(mOp.getVRegValue());
2344 else if(tmp->getType() == Type::DoubleTy)
2345 BuildMI(*kernelBB, I, V9::FMOVD, 3).addReg(tmp).addRegDef(mOp.getVRegValue());
2346 else
2347 BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
2348
2349
Tanya Lattnera6457502004-10-14 06:04:28 +00002350 worklist.push_back(std::make_pair(kernelBB, I));
2351 }
2352
2353 }
2354
2355 }
2356
Tanya Lattnera6457502004-10-14 06:04:28 +00002357
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002358 }
2359
Tanya Lattner80f08552004-11-02 21:04:56 +00002360 //Add TmpInstructions to some MCFI
2361 if(addToMCFI.size() > 0) {
2362 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
2363 for(unsigned x = 0; x < addToMCFI.size(); ++x) {
2364 tempMvec.addTemp(addToMCFI[x]);
2365 }
2366 addToMCFI.clear();
2367 }
2368
Tanya Lattnera6457502004-10-14 06:04:28 +00002369
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002370 //Remove phis from epilogue
2371 for(std::vector<MachineBasicBlock*>::iterator MB = epilogues.begin(), ME = epilogues.end(); MB != ME; ++MB) {
2372 for(MachineBasicBlock::iterator I = (*MB)->begin(), E = (*MB)->end(); I != E; ++I) {
Tanya Lattner80f08552004-11-02 21:04:56 +00002373
2374 DEBUG(std::cerr << "Looking at Instr: " << *I << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002375 //Get op code and check if its a phi
Brian Gaeke418379e2004-08-18 20:04:24 +00002376 if(I->getOpcode() == V9::PHI) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002377 Instruction *tmp = 0;
Tanya Lattnera6457502004-10-14 06:04:28 +00002378
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002379 for(unsigned i = 0; i < I->getNumOperands(); ++i) {
2380 //Get Operand
2381 const MachineOperand &mOp = I->getOperand(i);
2382 assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
2383
2384 if(!tmp) {
2385 tmp = new TmpInstruction(mOp.getVRegValue());
Tanya Lattnera6457502004-10-14 06:04:28 +00002386 addToMCFI.push_back(tmp);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002387 }
2388
2389 //Now for all our arguments we read, OR to the new TmpInstruction that we created
2390 if(mOp.isUse()) {
2391 DEBUG(std::cerr << "Use: " << mOp << "\n");
2392 //Place a copy at the end of its BB but before the branches
2393 assert(newValLocation.count(mOp.getVRegValue()) && "We must know where this value is located\n");
2394 //Reverse iterate to find the branches, we can safely assume no instructions have been
2395 //put in the nop positions
2396 for(MachineBasicBlock::iterator inst = --(newValLocation[mOp.getVRegValue()])->end(), endBB = (newValLocation[mOp.getVRegValue()])->begin(); inst != endBB; --inst) {
2397 MachineOpCode opc = inst->getOpcode();
2398 if(TMI->isBranch(opc) || TMI->isNop(opc))
2399 continue;
2400 else {
Tanya Lattner9532ab92005-03-23 01:47:20 +00002401 if(mOp.getVRegValue()->getType() == Type::FloatTy)
2402 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVS, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
2403 else if(mOp.getVRegValue()->getType() == Type::DoubleTy)
2404 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::FMOVD, 3).addReg(mOp.getVRegValue()).addRegDef(tmp);
2405 else
2406 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
2407
2408
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002409 break;
2410 }
2411
2412 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002413
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002414 }
2415 else {
2416 //Remove the phi and replace it with an OR
2417 DEBUG(std::cerr << "Def: " << mOp << "\n");
Tanya Lattner9532ab92005-03-23 01:47:20 +00002418 if(tmp->getType() == Type::FloatTy)
2419 BuildMI(**MB, I, V9::FMOVS, 3).addReg(tmp).addRegDef(mOp.getVRegValue());
2420 else if(tmp->getType() == Type::DoubleTy)
2421 BuildMI(**MB, I, V9::FMOVD, 3).addReg(tmp).addRegDef(mOp.getVRegValue());
2422 else
2423 BuildMI(**MB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
2424
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002425 worklist.push_back(std::make_pair(*MB,I));
2426 }
2427
2428 }
2429 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002430
Tanya Lattner80f08552004-11-02 21:04:56 +00002431
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002432 }
2433 }
2434
Tanya Lattner80f08552004-11-02 21:04:56 +00002435
2436 if(addToMCFI.size() > 0) {
2437 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
2438 for(unsigned x = 0; x < addToMCFI.size(); ++x) {
2439 tempMvec.addTemp(addToMCFI[x]);
2440 }
2441 addToMCFI.clear();
2442 }
2443
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002444 //Delete the phis
2445 for(std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> >::iterator I = worklist.begin(), E = worklist.end(); I != E; ++I) {
Tanya Lattnera6457502004-10-14 06:04:28 +00002446
2447 DEBUG(std::cerr << "Deleting PHI " << *I->second << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002448 I->first->erase(I->second);
2449
2450 }
2451
Tanya Lattnera6457502004-10-14 06:04:28 +00002452
2453 assert((addToMCFI.size() == 0) && "We should have added all TmpInstructions to some MachineCodeForInstruction");
Tanya Lattner20890832004-05-28 20:14:12 +00002454}
2455
2456
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002457void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002458
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00002459 TIME_REGION(X, "reconstructLoop");
2460
2461
Tanya Lattner420025b2004-10-10 22:44:35 +00002462 DEBUG(std::cerr << "Reconstructing Loop\n");
2463
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002464 //First find the value *'s that we need to "save"
Tanya Lattner9532ab92005-03-23 01:47:20 +00002465 std::map<const Value*, std::pair<const MachineInstr*, int> > valuesToSave;
Tanya Lattner4cffb582004-05-26 06:27:18 +00002466
Tanya Lattner420025b2004-10-10 22:44:35 +00002467 //Keep track of instructions we have already seen and their stage because
2468 //we don't want to "save" values if they are used in the kernel immediately
2469 std::map<const MachineInstr*, int> lastInstrs;
2470
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002471 //Loop over kernel and only look at instructions from a stage > 0
2472 //Look at its operands and save values *'s that are read
Tanya Lattner4cffb582004-05-26 06:27:18 +00002473 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002474
Tanya Lattner420025b2004-10-10 22:44:35 +00002475 if(I->second !=0) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002476 //For this instruction, get the Value*'s that it reads and put them into the set.
2477 //Assert if there is an operand of another type that we need to save
Tanya Lattner9532ab92005-03-23 01:47:20 +00002478 const MachineInstr *inst = I->first;
Tanya Lattner420025b2004-10-10 22:44:35 +00002479 lastInstrs[inst] = I->second;
2480
Tanya Lattner4cffb582004-05-26 06:27:18 +00002481 for(unsigned i=0; i < inst->getNumOperands(); ++i) {
2482 //get machine operand
2483 const MachineOperand &mOp = inst->getOperand(i);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002484
Tanya Lattner4cffb582004-05-26 06:27:18 +00002485 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
2486 //find the value in the map
Tanya Lattner420025b2004-10-10 22:44:35 +00002487 if (const Value* srcI = mOp.getVRegValue()) {
2488
Tanya Lattnerced82222004-11-16 21:31:37 +00002489 if(isa<Constant>(srcI) || isa<Argument>(srcI) || isa<PHINode>(srcI))
Tanya Lattner80f08552004-11-02 21:04:56 +00002490 continue;
2491
Tanya Lattner420025b2004-10-10 22:44:35 +00002492 //Before we declare this Value* one that we should save
2493 //make sure its def is not of the same stage as this instruction
2494 //because it will be consumed before its used
2495 Instruction *defInst = (Instruction*) srcI;
2496
2497 //Should we save this value?
2498 bool save = true;
2499
Tanya Lattnerced82222004-11-16 21:31:37 +00002500 //Continue if not in the def map, loop invariant code does not need to be saved
2501 if(!defMap.count(srcI))
2502 continue;
2503
Tanya Lattner80f08552004-11-02 21:04:56 +00002504 MachineInstr *defInstr = defMap[srcI];
2505
Tanya Lattnerced82222004-11-16 21:31:37 +00002506
Tanya Lattner80f08552004-11-02 21:04:56 +00002507 if(lastInstrs.count(defInstr)) {
Tanya Lattnerced82222004-11-16 21:31:37 +00002508 if(lastInstrs[defInstr] == I->second) {
Tanya Lattner80f08552004-11-02 21:04:56 +00002509 save = false;
Tanya Lattnerced82222004-11-16 21:31:37 +00002510
2511 }
Tanya Lattner420025b2004-10-10 22:44:35 +00002512 }
Tanya Lattner80f08552004-11-02 21:04:56 +00002513
Tanya Lattner420025b2004-10-10 22:44:35 +00002514 if(save)
2515 valuesToSave[srcI] = std::make_pair(I->first, i);
2516 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00002517 }
2518
2519 if(mOp.getType() != MachineOperand::MO_VirtualRegister && mOp.isUse()) {
2520 assert("Our assumption is wrong. We have another type of register that needs to be saved\n");
2521 }
2522 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00002523 }
2524 }
2525
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002526 //The new loop will consist of one or more prologues, the kernel, and one or more epilogues.
2527
2528 //Map to keep track of old to new values
Tanya Lattner420025b2004-10-10 22:44:35 +00002529 std::map<Value*, std::map<int, Value*> > newValues;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002530
Tanya Lattner420025b2004-10-10 22:44:35 +00002531 //Map to keep track of old to new values in kernel
2532 std::map<Value*, std::map<int, Value*> > kernelPHIs;
2533
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002534 //Another map to keep track of what machine basic blocks these new value*s are in since
2535 //they have no llvm instruction equivalent
2536 std::map<Value*, MachineBasicBlock*> newValLocation;
2537
2538 std::vector<MachineBasicBlock*> prologues;
2539 std::vector<BasicBlock*> llvm_prologues;
2540
2541
2542 //Write prologue
2543 writePrologues(prologues, BB, llvm_prologues, valuesToSave, newValues, newValLocation);
Tanya Lattner420025b2004-10-10 22:44:35 +00002544
2545 //Print out epilogues and prologue
2546 DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = prologues.begin(), E = prologues.end();
2547 I != E; ++I) {
2548 std::cerr << "PROLOGUE\n";
2549 (*I)->print(std::cerr);
2550 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002551
2552 BasicBlock *llvmKernelBB = new BasicBlock("Kernel", (Function*) (BB->getBasicBlock()->getParent()));
2553 MachineBasicBlock *machineKernelBB = new MachineBasicBlock(llvmKernelBB);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002554 (((MachineBasicBlock*)BB)->getParent())->getBasicBlockList().push_back(machineKernelBB);
Tanya Lattner420025b2004-10-10 22:44:35 +00002555 writeKernel(llvmKernelBB, machineKernelBB, valuesToSave, newValues, newValLocation, kernelPHIs);
2556
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002557
2558 std::vector<MachineBasicBlock*> epilogues;
2559 std::vector<BasicBlock*> llvm_epilogues;
2560
2561 //Write epilogues
Tanya Lattner420025b2004-10-10 22:44:35 +00002562 writeEpilogues(epilogues, BB, llvm_epilogues, valuesToSave, newValues, newValLocation, kernelPHIs);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002563
2564
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002565 //Fix our branches
2566 fixBranches(prologues, llvm_prologues, machineKernelBB, llvmKernelBB, epilogues, llvm_epilogues, BB);
2567
2568 //Remove phis
2569 removePHIs(BB, prologues, epilogues, machineKernelBB, newValLocation);
2570
2571 //Print out epilogues and prologue
2572 DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = prologues.begin(), E = prologues.end();
2573 I != E; ++I) {
2574 std::cerr << "PROLOGUE\n";
2575 (*I)->print(std::cerr);
2576 });
2577
2578 DEBUG(std::cerr << "KERNEL\n");
2579 DEBUG(machineKernelBB->print(std::cerr));
2580
2581 DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = epilogues.begin(), E = epilogues.end();
2582 I != E; ++I) {
2583 std::cerr << "EPILOGUE\n";
2584 (*I)->print(std::cerr);
2585 });
2586
2587
2588 DEBUG(std::cerr << "New Machine Function" << "\n");
2589 DEBUG(std::cerr << BB->getParent() << "\n");
2590
2591
2592}
2593
2594void ModuloSchedulingPass::fixBranches(std::vector<MachineBasicBlock *> &prologues, std::vector<BasicBlock*> &llvm_prologues, MachineBasicBlock *machineKernelBB, BasicBlock *llvmKernelBB, std::vector<MachineBasicBlock *> &epilogues, std::vector<BasicBlock*> &llvm_epilogues, MachineBasicBlock *BB) {
2595
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002596 const TargetInstrInfo *TMI = target.getInstrInfo();
2597
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002598 //Fix prologue branches
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002599 for(unsigned I = 0; I < prologues.size(); ++I) {
2600
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002601 //Find terminator since getFirstTerminator does not work!
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002602 for(MachineBasicBlock::reverse_iterator mInst = prologues[I]->rbegin(), mInstEnd = prologues[I]->rend(); mInst != mInstEnd; ++mInst) {
2603 MachineOpCode OC = mInst->getOpcode();
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002604 //If its a branch update its branchto
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002605 if(TMI->isBranch(OC)) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002606 for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) {
2607 MachineOperand &mOp = mInst->getOperand(opNum);
2608 if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2609 //Check if we are branching to the kernel, if not branch to epilogue
2610 if(mOp.getVRegValue() == BB->getBasicBlock()) {
2611 if(I == prologues.size()-1)
2612 mOp.setValueReg(llvmKernelBB);
2613 else
2614 mOp.setValueReg(llvm_prologues[I+1]);
2615 }
2616 else {
2617 mOp.setValueReg(llvm_epilogues[(llvm_epilogues.size()-1-I)]);
2618 }
2619 }
2620 }
2621
2622 DEBUG(std::cerr << "New Prologue Branch: " << *mInst << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002623 }
2624 }
2625
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002626
2627 //Update llvm basic block with our new branch instr
2628 DEBUG(std::cerr << BB->getBasicBlock()->getTerminator() << "\n");
2629 const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002630
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002631 if(I == prologues.size()-1) {
2632 TerminatorInst *newBranch = new BranchInst(llvmKernelBB,
2633 llvm_epilogues[(llvm_epilogues.size()-1-I)],
Tanya Lattnera6457502004-10-14 06:04:28 +00002634 branchVal->getCondition(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002635 llvm_prologues[I]);
2636 }
2637 else
2638 TerminatorInst *newBranch = new BranchInst(llvm_prologues[I+1],
2639 llvm_epilogues[(llvm_epilogues.size()-1-I)],
Tanya Lattnera6457502004-10-14 06:04:28 +00002640 branchVal->getCondition(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002641 llvm_prologues[I]);
2642
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002643 }
2644
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002645 Value *origBranchExit = 0;
Tanya Lattnera6457502004-10-14 06:04:28 +00002646
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002647 //Fix up kernel machine branches
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002648 for(MachineBasicBlock::reverse_iterator mInst = machineKernelBB->rbegin(), mInstEnd = machineKernelBB->rend(); mInst != mInstEnd; ++mInst) {
2649 MachineOpCode OC = mInst->getOpcode();
2650 if(TMI->isBranch(OC)) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002651 for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) {
2652 MachineOperand &mOp = mInst->getOperand(opNum);
2653
2654 if(mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2655 if(mOp.getVRegValue() == BB->getBasicBlock())
2656 mOp.setValueReg(llvmKernelBB);
2657 else
2658 if(llvm_epilogues.size() > 0) {
2659 assert(origBranchExit == 0 && "There should only be one branch out of the loop");
2660
2661 origBranchExit = mOp.getVRegValue();
2662 mOp.setValueReg(llvm_epilogues[0]);
2663 }
2664 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002665 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002666 }
2667 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002668
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002669 //Update kernelLLVM branches
2670 const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
Tanya Lattnera6457502004-10-14 06:04:28 +00002671
Tanya Lattner260652a2004-10-30 00:39:07 +00002672 assert(llvm_epilogues.size() != 0 && "We must have epilogues!");
2673
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002674 TerminatorInst *newBranch = new BranchInst(llvmKernelBB,
2675 llvm_epilogues[0],
Tanya Lattnera6457502004-10-14 06:04:28 +00002676 branchVal->getCondition(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002677 llvmKernelBB);
2678
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002679
2680 //Lastly add unconditional branches for the epilogues
2681 for(unsigned I = 0; I < epilogues.size(); ++I) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002682
Tanya Lattnera6457502004-10-14 06:04:28 +00002683 //Now since we don't have fall throughs, add a unconditional branch to the next prologue
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002684 if(I != epilogues.size()-1) {
Tanya Lattner420025b2004-10-10 22:44:35 +00002685 BuildMI(epilogues[I], V9::BA, 1).addPCDisp(llvm_epilogues[I+1]);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002686 //Add unconditional branch to end of epilogue
2687 TerminatorInst *newBranch = new BranchInst(llvm_epilogues[I+1],
2688 llvm_epilogues[I]);
2689
Tanya Lattner4cffb582004-05-26 06:27:18 +00002690 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002691 else {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002692 BuildMI(epilogues[I], V9::BA, 1).addPCDisp(origBranchExit);
Tanya Lattnera6457502004-10-14 06:04:28 +00002693
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002694
Tanya Lattnera6457502004-10-14 06:04:28 +00002695 //Update last epilogue exit branch
2696 BranchInst *branchVal = (BranchInst*) dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
2697 //Find where we are supposed to branch to
2698 BasicBlock *nextBlock = 0;
2699 for(unsigned j=0; j <branchVal->getNumSuccessors(); ++j) {
2700 if(branchVal->getSuccessor(j) != BB->getBasicBlock())
2701 nextBlock = branchVal->getSuccessor(j);
2702 }
2703
2704 assert((nextBlock != 0) && "Next block should not be null!");
2705 TerminatorInst *newBranch = new BranchInst(nextBlock, llvm_epilogues[I]);
2706 }
2707 //Add one more nop!
2708 BuildMI(epilogues[I], V9::NOP, 0);
2709
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002710 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00002711
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002712 //FIX UP Machine BB entry!!
2713 //We are looking at the predecesor of our loop basic block and we want to change its ba instruction
2714
Tanya Lattner4cffb582004-05-26 06:27:18 +00002715
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002716 //Find all llvm basic blocks that branch to the loop entry and change to our first prologue.
2717 const BasicBlock *llvmBB = BB->getBasicBlock();
2718
Tanya Lattner260652a2004-10-30 00:39:07 +00002719 std::vector<const BasicBlock*>Preds (pred_begin(llvmBB), pred_end(llvmBB));
2720
2721 //for(pred_const_iterator P = pred_begin(llvmBB), PE = pred_end(llvmBB); P != PE; ++PE) {
2722 for(std::vector<const BasicBlock*>::iterator P = Preds.begin(), PE = Preds.end(); P != PE; ++P) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002723 if(*P == llvmBB)
2724 continue;
2725 else {
2726 DEBUG(std::cerr << "Found our entry BB\n");
2727 //Get the Terminator instruction for this basic block and print it out
2728 DEBUG(std::cerr << *((*P)->getTerminator()) << "\n");
2729 //Update the terminator
2730 TerminatorInst *term = ((BasicBlock*)*P)->getTerminator();
2731 for(unsigned i=0; i < term->getNumSuccessors(); ++i) {
2732 if(term->getSuccessor(i) == llvmBB) {
2733 DEBUG(std::cerr << "Replacing successor bb\n");
2734 if(llvm_prologues.size() > 0) {
2735 term->setSuccessor(i, llvm_prologues[0]);
2736 //Also update its corresponding machine instruction
2737 MachineCodeForInstruction & tempMvec =
2738 MachineCodeForInstruction::get(term);
2739 for (unsigned j = 0; j < tempMvec.size(); j++) {
2740 MachineInstr *temp = tempMvec[j];
2741 MachineOpCode opc = temp->getOpcode();
2742 if(TMI->isBranch(opc)) {
2743 DEBUG(std::cerr << *temp << "\n");
2744 //Update branch
2745 for(unsigned opNum = 0; opNum < temp->getNumOperands(); ++opNum) {
2746 MachineOperand &mOp = temp->getOperand(opNum);
2747 if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2748 mOp.setValueReg(llvm_prologues[0]);
2749 }
2750 }
2751 }
2752 }
2753 }
2754 else {
2755 term->setSuccessor(i, llvmKernelBB);
2756 //Also update its corresponding machine instruction
2757 MachineCodeForInstruction & tempMvec =
2758 MachineCodeForInstruction::get(term);
2759 for (unsigned j = 0; j < tempMvec.size(); j++) {
2760 MachineInstr *temp = tempMvec[j];
2761 MachineOpCode opc = temp->getOpcode();
2762 if(TMI->isBranch(opc)) {
2763 DEBUG(std::cerr << *temp << "\n");
2764 //Update branch
2765 for(unsigned opNum = 0; opNum < temp->getNumOperands(); ++opNum) {
2766 MachineOperand &mOp = temp->getOperand(opNum);
2767 if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2768 mOp.setValueReg(llvmKernelBB);
2769 }
2770 }
2771 }
2772 }
2773 }
2774 }
2775 }
2776 break;
2777 }
2778 }
2779
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002780
Tanya Lattner420025b2004-10-10 22:44:35 +00002781 //BB->getParent()->getBasicBlockList().erase(BB);
Tanya Lattner4cffb582004-05-26 06:27:18 +00002782
2783}
2784