blob: 15dc5b32ce6aad3539ffbdaade4978d835b1e442 [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 Lattner0a88d2d2004-07-30 23:36:10 +000018#include "llvm/Instructions.h"
19#include "llvm/Function.h"
Tanya Lattnerd14b8372004-03-01 02:50:01 +000020#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/Passes.h"
22#include "llvm/Support/CFG.h"
23#include "llvm/Target/TargetSchedInfo.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000024#include "llvm/Support/Debug.h"
25#include "llvm/Support/GraphWriter.h"
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000026#include "llvm/ADT/SCCIterator.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000027#include "llvm/ADT/StringExtras.h"
Tanya Lattnere1df2122004-11-22 20:41:24 +000028#include "llvm/ADT/Statistic.h"
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000029#include "llvm/Support/Timer.h"
Misha Brukman82fd8d82004-08-02 13:59:10 +000030#include <cmath>
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +000031#include <algorithm>
Tanya Lattnerd14b8372004-03-01 02:50:01 +000032#include <fstream>
33#include <sstream>
Misha Brukman82fd8d82004-08-02 13:59:10 +000034#include <utility>
35#include <vector>
Misha Brukman7da1e6e2004-10-10 23:34:50 +000036#include "../MachineCodeForInstruction.h"
37#include "../SparcV9TmpInstr.h"
38#include "../SparcV9Internals.h"
39#include "../SparcV9RegisterInfo.h"
Tanya Lattnerd14b8372004-03-01 02:50:01 +000040using namespace llvm;
41
42/// Create ModuloSchedulingPass
43///
44FunctionPass *llvm::createModuloSchedulingPass(TargetMachine & targ) {
45 DEBUG(std::cerr << "Created ModuloSchedulingPass\n");
46 return new ModuloSchedulingPass(targ);
47}
48
Tanya Lattner0a88d2d2004-07-30 23:36:10 +000049
50//Graph Traits for printing out the dependence graph
Tanya Lattnerd14b8372004-03-01 02:50:01 +000051template<typename GraphType>
52static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
53 const GraphType &GT) {
54 std::string Filename = GraphName + ".dot";
55 O << "Writing '" << Filename << "'...";
56 std::ofstream F(Filename.c_str());
57
58 if (F.good())
59 WriteGraph(F, GT);
60 else
61 O << " error opening file for writing!";
62 O << "\n";
63};
Guochun Shif1c154f2003-03-27 17:57:44 +000064
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000065
66#if 1
67#define TIME_REGION(VARNAME, DESC) \
68 NamedRegionTimer VARNAME(DESC)
69#else
70#define TIME_REGION(VARNAME, DESC)
71#endif
72
73
Tanya Lattner0a88d2d2004-07-30 23:36:10 +000074//Graph Traits for printing out the dependence graph
Brian Gaeked0fde302003-11-11 22:41:34 +000075namespace llvm {
Tanya Lattnere1df2122004-11-22 20:41:24 +000076 Statistic<> ValidLoops("modulosched-validLoops", "Number of candidate loops modulo-scheduled");
77 Statistic<> MSLoops("modulosched-schedLoops", "Number of loops successfully modulo-scheduled");
78 Statistic<> IncreasedII("modulosched-increasedII", "Number of times we had to increase II");
Tanya Lattnerdb40cf12005-02-10 17:02:58 +000079 Statistic<> SingleBBLoops("modulosched-singeBBLoops", "Number of single basic block loops");
Brian Gaeked0fde302003-11-11 22:41:34 +000080
Tanya Lattnerd14b8372004-03-01 02:50:01 +000081 template<>
82 struct DOTGraphTraits<MSchedGraph*> : public DefaultDOTGraphTraits {
83 static std::string getGraphName(MSchedGraph *F) {
84 return "Dependence Graph";
85 }
Guochun Shi8f1d4ab2003-06-08 23:16:07 +000086
Tanya Lattnerd14b8372004-03-01 02:50:01 +000087 static std::string getNodeLabel(MSchedGraphNode *Node, MSchedGraph *Graph) {
88 if (Node->getInst()) {
89 std::stringstream ss;
90 ss << *(Node->getInst());
91 return ss.str(); //((MachineInstr*)Node->getInst());
92 }
93 else
94 return "No Inst";
95 }
96 static std::string getEdgeSourceLabel(MSchedGraphNode *Node,
97 MSchedGraphNode::succ_iterator I) {
98 //Label each edge with the type of dependence
99 std::string edgelabel = "";
100 switch (I.getEdge().getDepOrderType()) {
101
102 case MSchedGraphEdge::TrueDep:
103 edgelabel = "True";
104 break;
105
106 case MSchedGraphEdge::AntiDep:
107 edgelabel = "Anti";
108 break;
109
110 case MSchedGraphEdge::OutputDep:
111 edgelabel = "Output";
112 break;
113
114 default:
115 edgelabel = "Unknown";
116 break;
117 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000118
119 //FIXME
120 int iteDiff = I.getEdge().getIteDiff();
121 std::string intStr = "(IteDiff: ";
122 intStr += itostr(iteDiff);
123
124 intStr += ")";
125 edgelabel += intStr;
126
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000127 return edgelabel;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000128 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000129 };
Guochun Shif1c154f2003-03-27 17:57:44 +0000130}
Tanya Lattner4f839cc2003-08-28 17:12:14 +0000131
Misha Brukmanaa41c3c2003-10-10 17:41:32 +0000132/// ModuloScheduling::runOnFunction - main transformation entry point
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000133/// The Swing Modulo Schedule algorithm has three basic steps:
134/// 1) Computation and Analysis of the dependence graph
135/// 2) Ordering of the nodes
136/// 3) Scheduling
137///
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000138bool ModuloSchedulingPass::runOnFunction(Function &F) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000139
Tanya Lattner4f839cc2003-08-28 17:12:14 +0000140 bool Changed = false;
Tanya Lattnerced82222004-11-16 21:31:37 +0000141 int numMS = 0;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000142
Tanya Lattner420025b2004-10-10 22:44:35 +0000143 DEBUG(std::cerr << "Creating ModuloSchedGraph for each valid BasicBlock in " + F.getName() + "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000144
145 //Get MachineFunction
146 MachineFunction &MF = MachineFunction::get(&F);
Tanya Lattner260652a2004-10-30 00:39:07 +0000147
148
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000149 //Worklist
150 std::vector<MachineBasicBlock*> Worklist;
151
152 //Iterate over BasicBlocks and put them into our worklist if they are valid
153 for (MachineFunction::iterator BI = MF.begin(); BI != MF.end(); ++BI)
Tanya Lattnere1df2122004-11-22 20:41:24 +0000154 if(MachineBBisValid(BI)) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000155 Worklist.push_back(&*BI);
Tanya Lattnere1df2122004-11-22 20:41:24 +0000156 ++ValidLoops;
157 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000158
Tanya Lattner80f08552004-11-02 21:04:56 +0000159 defaultInst = 0;
160
Tanya Lattner420025b2004-10-10 22:44:35 +0000161 DEBUG(if(Worklist.size() == 0) std::cerr << "No single basic block loops in function to ModuloSchedule\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000162
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000163 //Iterate over the worklist and perform scheduling
164 for(std::vector<MachineBasicBlock*>::iterator BI = Worklist.begin(),
165 BE = Worklist.end(); BI != BE; ++BI) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000166
167 //Print out BB for debugging
168 DEBUG(std::cerr << "ModuloScheduling BB: \n"; (*BI)->print(std::cerr));
169
170 //Catch the odd case where we only have TmpInstructions and no real Value*s
171 if(!CreateDefMap(*BI)) {
172 //Clear out our maps for the next basic block that is processed
173 nodeToAttributesMap.clear();
174 partialOrder.clear();
175 recurrenceList.clear();
176 FinalNodeOrder.clear();
177 schedule.clear();
178 defMap.clear();
179 continue;
180 }
Tanya Lattnerced82222004-11-16 21:31:37 +0000181
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000182 MSchedGraph *MSG = new MSchedGraph(*BI, target);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000183
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000184 //Write Graph out to file
185 DEBUG(WriteGraphToFile(std::cerr, F.getName(), MSG));
186
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000187 //Calculate Resource II
188 int ResMII = calculateResMII(*BI);
189
190 //Calculate Recurrence II
191 int RecMII = calculateRecMII(MSG, ResMII);
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000192
193 DEBUG(std::cerr << "Number of reccurrences found: " << recurrenceList.size() << "\n");
194
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000195
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000196
197
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000198 //Our starting initiation interval is the maximum of RecMII and ResMII
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000199 II = std::max(RecMII, ResMII);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000200
201 //Print out II, RecMII, and ResMII
Tanya Lattner260652a2004-10-30 00:39:07 +0000202 DEBUG(std::cerr << "II starts out as " << II << " ( RecMII=" << RecMII << " and ResMII=" << ResMII << ")\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000203
Tanya Lattner260652a2004-10-30 00:39:07 +0000204 //Dump node properties if in debug mode
205 DEBUG(for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
206 E = nodeToAttributesMap.end(); I !=E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000207 std::cerr << "Node: " << *(I->first) << " ASAP: " << I->second.ASAP << " ALAP: "
208 << I->second.ALAP << " MOB: " << I->second.MOB << " Depth: " << I->second.depth
209 << " Height: " << I->second.height << "\n";
210 });
Tanya Lattner260652a2004-10-30 00:39:07 +0000211
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000212 //Calculate Node Properties
213 calculateNodeAttributes(MSG, ResMII);
214
215 //Dump node properties if in debug mode
216 DEBUG(for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
217 E = nodeToAttributesMap.end(); I !=E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000218 std::cerr << "Node: " << *(I->first) << " ASAP: " << I->second.ASAP << " ALAP: "
219 << I->second.ALAP << " MOB: " << I->second.MOB << " Depth: " << I->second.depth
220 << " Height: " << I->second.height << "\n";
221 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000222
223 //Put nodes in order to schedule them
224 computePartialOrder();
225
226 //Dump out partial order
Tanya Lattner260652a2004-10-30 00:39:07 +0000227 DEBUG(for(std::vector<std::set<MSchedGraphNode*> >::iterator I = partialOrder.begin(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000228 E = partialOrder.end(); I !=E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000229 std::cerr << "Start set in PO\n";
230 for(std::set<MSchedGraphNode*>::iterator J = I->begin(), JE = I->end(); J != JE; ++J)
231 std::cerr << "PO:" << **J << "\n";
232 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000233
234 //Place nodes in final order
235 orderNodes();
236
237 //Dump out order of nodes
238 DEBUG(for(std::vector<MSchedGraphNode*>::iterator I = FinalNodeOrder.begin(), E = FinalNodeOrder.end(); I != E; ++I) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000239 std::cerr << "FO:" << **I << "\n";
240 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000241
242 //Finally schedule nodes
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000243 bool haveSched = computeSchedule();
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000244
245 //Print out final schedule
246 DEBUG(schedule.print(std::cerr));
247
Tanya Lattner260652a2004-10-30 00:39:07 +0000248 //Final scheduling step is to reconstruct the loop only if we actual have
249 //stage > 0
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000250 if(schedule.getMaxStage() != 0 && haveSched) {
Tanya Lattner260652a2004-10-30 00:39:07 +0000251 reconstructLoop(*BI);
Tanya Lattnere1df2122004-11-22 20:41:24 +0000252 ++MSLoops;
Tanya Lattnerced82222004-11-16 21:31:37 +0000253 Changed = true;
254 }
Tanya Lattner260652a2004-10-30 00:39:07 +0000255 else
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000256 DEBUG(std::cerr << "Max stage is 0, so no change in loop or reached cap\n");
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000257
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000258 //Clear out our maps for the next basic block that is processed
259 nodeToAttributesMap.clear();
260 partialOrder.clear();
261 recurrenceList.clear();
262 FinalNodeOrder.clear();
263 schedule.clear();
Tanya Lattnerced82222004-11-16 21:31:37 +0000264 defMap.clear();
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000265 //Clean up. Nuke old MachineBB and llvmBB
266 //BasicBlock *llvmBB = (BasicBlock*) (*BI)->getBasicBlock();
267 //Function *parent = (Function*) llvmBB->getParent();
268 //Should't std::find work??
269 //parent->getBasicBlockList().erase(std::find(parent->getBasicBlockList().begin(), parent->getBasicBlockList().end(), *llvmBB));
270 //parent->getBasicBlockList().erase(llvmBB);
271
272 //delete(llvmBB);
273 //delete(*BI);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000274 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000275
Tanya Lattner4f839cc2003-08-28 17:12:14 +0000276 return Changed;
277}
Brian Gaeked0fde302003-11-11 22:41:34 +0000278
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000279bool ModuloSchedulingPass::CreateDefMap(MachineBasicBlock *BI) {
Tanya Lattnerced82222004-11-16 21:31:37 +0000280 defaultInst = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000281
Tanya Lattnerced82222004-11-16 21:31:37 +0000282 for(MachineBasicBlock::iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
283 for(unsigned opNum = 0; opNum < I->getNumOperands(); ++opNum) {
284 const MachineOperand &mOp = I->getOperand(opNum);
285 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
Tanya Lattnere1df2122004-11-22 20:41:24 +0000286 //assert if this is the second def we have seen
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000287 //DEBUG(std::cerr << "Putting " << *(mOp.getVRegValue()) << " into map\n");
Tanya Lattnere1df2122004-11-22 20:41:24 +0000288 assert(!defMap.count(mOp.getVRegValue()) && "Def already in the map");
289
Tanya Lattnerced82222004-11-16 21:31:37 +0000290 defMap[mOp.getVRegValue()] = &*I;
291 }
292
293 //See if we can use this Value* as our defaultInst
294 if(!defaultInst && mOp.getType() == MachineOperand::MO_VirtualRegister) {
295 Value *V = mOp.getVRegValue();
296 if(!isa<TmpInstruction>(V) && !isa<Argument>(V) && !isa<Constant>(V) && !isa<PHINode>(V))
297 defaultInst = (Instruction*) V;
298 }
299 }
300 }
Tanya Lattnere1df2122004-11-22 20:41:24 +0000301
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000302 if(!defaultInst)
303 return false;
304
305 return true;
Tanya Lattnerced82222004-11-16 21:31:37 +0000306
307}
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000308/// This function checks if a Machine Basic Block is valid for modulo
309/// scheduling. This means that it has no control flow (if/else or
310/// calls) in the block. Currently ModuloScheduling only works on
311/// single basic block loops.
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000312bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) {
313
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000314 bool isLoop = false;
315
316 //Check first if its a valid loop
317 for(succ_const_iterator I = succ_begin(BI->getBasicBlock()),
318 E = succ_end(BI->getBasicBlock()); I != E; ++I) {
319 if (*I == BI->getBasicBlock()) // has single block loop
320 isLoop = true;
321 }
322
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000323 if(!isLoop)
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000324 return false;
Tanya Lattnerad7654f2004-12-02 07:22:15 +0000325
326 //Check that we have a conditional branch (avoiding MS infinite loops)
327 if(BranchInst *b = dyn_cast<BranchInst>(((BasicBlock*) BI->getBasicBlock())->getTerminator()))
328 if(b->isUnconditional())
329 return false;
330
Tanya Lattnere1df2122004-11-22 20:41:24 +0000331 //Check size of our basic block.. make sure we have more then just the terminator in it
332 if(BI->getBasicBlock()->size() == 1)
333 return false;
334
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000335
336 //Increase number of single basic block loops for stats
337 ++SingleBBLoops;
338
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000339 //Get Target machine instruction info
340 const TargetInstrInfo *TMI = target.getInstrInfo();
341
342 //Check each instruction and look for calls
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000343 for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000344 //Get opcode to check instruction type
345 MachineOpCode OC = I->getOpcode();
346 if(TMI->isCall(OC))
347 return false;
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000348 //Look for conditional move
349 if(OC == V9::MOVRZr || OC == V9::MOVRZi || OC == V9::MOVRLEZr || OC == V9::MOVRLEZi
350 || OC == V9::MOVRLZr || OC == V9::MOVRLZi || OC == V9::MOVRNZr || OC == V9::MOVRNZi
351 || OC == V9::MOVRGZr || OC == V9::MOVRGZi || OC == V9::MOVRGEZr
352 || OC == V9::MOVRGEZi || OC == V9::MOVLEr || OC == V9::MOVLEi || OC == V9::MOVLEUr
353 || OC == V9::MOVLEUi || OC == V9::MOVFLEr || OC == V9::MOVFLEi
354 || OC == V9::MOVNEr || OC == V9::MOVNEi || OC == V9::MOVNEGr || OC == V9::MOVNEGi
355 || OC == V9::MOVFNEr || OC == V9::MOVFNEi)
356 return false;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000357 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000358 return true;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000359}
360
361//ResMII is calculated by determining the usage count for each resource
362//and using the maximum.
363//FIXME: In future there should be a way to get alternative resources
364//for each instruction
365int ModuloSchedulingPass::calculateResMII(const MachineBasicBlock *BI) {
366
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000367 TIME_REGION(X, "calculateResMII");
368
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000369 const TargetInstrInfo *mii = target.getInstrInfo();
370 const TargetSchedInfo *msi = target.getSchedInfo();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000371
372 int ResMII = 0;
373
374 //Map to keep track of usage count of each resource
375 std::map<unsigned, unsigned> resourceUsageCount;
376
377 for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) {
378
379 //Get resource usage for this instruction
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000380 InstrRUsage rUsage = msi->getInstrRUsage(I->getOpcode());
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000381 std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
382
383 //Loop over resources in each cycle and increments their usage count
384 for(unsigned i=0; i < resources.size(); ++i)
385 for(unsigned j=0; j < resources[i].size(); ++j) {
386 if( resourceUsageCount.find(resources[i][j]) == resourceUsageCount.end()) {
387 resourceUsageCount[resources[i][j]] = 1;
388 }
389 else {
390 resourceUsageCount[resources[i][j]] = resourceUsageCount[resources[i][j]] + 1;
391 }
392 }
393 }
394
395 //Find maximum usage count
396
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000397 //Get max number of instructions that can be issued at once. (FIXME)
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000398 int issueSlots = msi->maxNumIssueTotal;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000399
400 for(std::map<unsigned,unsigned>::iterator RB = resourceUsageCount.begin(), RE = resourceUsageCount.end(); RB != RE; ++RB) {
Tanya Lattner4cffb582004-05-26 06:27:18 +0000401
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000402 //Get the total number of the resources in our cpu
Tanya Lattner4cffb582004-05-26 06:27:18 +0000403 int resourceNum = CPUResource::getCPUResource(RB->first)->maxNumUsers;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000404
405 //Get total usage count for this resources
406 unsigned usageCount = RB->second;
407
408 //Divide the usage count by either the max number we can issue or the number of
409 //resources (whichever is its upper bound)
410 double finalUsageCount;
Tanya Lattner4cffb582004-05-26 06:27:18 +0000411 if( resourceNum <= issueSlots)
412 finalUsageCount = ceil(1.0 * usageCount / resourceNum);
413 else
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000414 finalUsageCount = ceil(1.0 * usageCount / issueSlots);
415
416
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000417 //Only keep track of the max
418 ResMII = std::max( (int) finalUsageCount, ResMII);
419
420 }
421
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000422 return ResMII;
423
424}
425
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000426/// calculateRecMII - Calculates the value of the highest recurrence
427/// By value we mean the total latency
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000428int ModuloSchedulingPass::calculateRecMII(MSchedGraph *graph, int MII) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000429 /*std::vector<MSchedGraphNode*> vNodes;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000430 //Loop over all nodes in the graph
431 for(MSchedGraph::iterator I = graph->begin(), E = graph->end(); I != E; ++I) {
432 findAllReccurrences(I->second, vNodes, MII);
433 vNodes.clear();
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000434 }*/
435
436 TIME_REGION(X, "calculateRecMII");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000437
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000438 findAllCircuits(graph, MII);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000439 int RecMII = 0;
440
441 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 +0000442 RecMII = std::max(RecMII, I->first);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000443 }
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000444
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000445 return MII;
446}
447
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000448/// calculateNodeAttributes - The following properties are calculated for
449/// each node in the dependence graph: ASAP, ALAP, Depth, Height, and
450/// MOB.
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000451void ModuloSchedulingPass::calculateNodeAttributes(MSchedGraph *graph, int MII) {
452
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000453 TIME_REGION(X, "calculateNodeAttributes");
454
Tanya Lattner260652a2004-10-30 00:39:07 +0000455 assert(nodeToAttributesMap.empty() && "Node attribute map was not cleared");
456
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000457 //Loop over the nodes and add them to the map
458 for(MSchedGraph::iterator I = graph->begin(), E = graph->end(); I != E; ++I) {
Tanya Lattner260652a2004-10-30 00:39:07 +0000459
460 DEBUG(std::cerr << "Inserting node into attribute map: " << *I->second << "\n");
461
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000462 //Assert if its already in the map
Tanya Lattner260652a2004-10-30 00:39:07 +0000463 assert(nodeToAttributesMap.count(I->second) == 0 &&
464 "Node attributes are already in the map");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000465
466 //Put into the map with default attribute values
467 nodeToAttributesMap[I->second] = MSNodeAttributes();
468 }
469
470 //Create set to deal with reccurrences
471 std::set<MSchedGraphNode*> visitedNodes;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000472
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000473 //Now Loop over map and calculate the node attributes
474 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000475 calculateASAP(I->first, MII, (MSchedGraphNode*) 0);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000476 visitedNodes.clear();
477 }
478
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000479 int maxASAP = findMaxASAP();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000480 //Calculate ALAP which depends on ASAP being totally calculated
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000481 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
482 calculateALAP(I->first, MII, maxASAP, (MSchedGraphNode*) 0);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000483 visitedNodes.clear();
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000484 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000485
486 //Calculate MOB which depends on ASAP being totally calculated, also do depth and height
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000487 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
488 (I->second).MOB = std::max(0,(I->second).ALAP - (I->second).ASAP);
489
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000490 DEBUG(std::cerr << "MOB: " << (I->second).MOB << " (" << *(I->first) << ")\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000491 calculateDepth(I->first, (MSchedGraphNode*) 0);
492 calculateHeight(I->first, (MSchedGraphNode*) 0);
493 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000494
495
496}
497
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000498/// ignoreEdge - Checks to see if this edge of a recurrence should be ignored or not
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000499bool ModuloSchedulingPass::ignoreEdge(MSchedGraphNode *srcNode, MSchedGraphNode *destNode) {
500 if(destNode == 0 || srcNode ==0)
501 return false;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000502
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000503 bool findEdge = edgesToIgnore.count(std::make_pair(srcNode, destNode->getInEdgeNum(srcNode)));
Tanya Lattner4cffb582004-05-26 06:27:18 +0000504
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000505 return findEdge;
506}
507
Tanya Lattner0a88d2d2004-07-30 23:36:10 +0000508
509/// calculateASAP - Calculates the
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000510int ModuloSchedulingPass::calculateASAP(MSchedGraphNode *node, int MII, MSchedGraphNode *destNode) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000511
512 DEBUG(std::cerr << "Calculating ASAP for " << *node << "\n");
513
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000514 //Get current node attributes
515 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
516
517 if(attributes.ASAP != -1)
518 return attributes.ASAP;
519
520 int maxPredValue = 0;
521
522 //Iterate over all of the predecessors and find max
523 for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000524
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000525 //Only process if we are not ignoring the edge
526 if(!ignoreEdge(*P, node)) {
527 int predASAP = -1;
528 predASAP = calculateASAP(*P, MII, node);
529
530 assert(predASAP != -1 && "ASAP has not been calculated");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000531 int iteDiff = node->getInEdge(*P).getIteDiff();
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000532
533 int currentPredValue = predASAP + (*P)->getLatency() - (iteDiff * MII);
534 DEBUG(std::cerr << "pred ASAP: " << predASAP << ", iteDiff: " << iteDiff << ", PredLatency: " << (*P)->getLatency() << ", Current ASAP pred: " << currentPredValue << "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000535 maxPredValue = std::max(maxPredValue, currentPredValue);
536 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000537 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000538
539 attributes.ASAP = maxPredValue;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000540
541 DEBUG(std::cerr << "ASAP: " << attributes.ASAP << " (" << *node << ")\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000542
543 return maxPredValue;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000544}
545
546
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000547int ModuloSchedulingPass::calculateALAP(MSchedGraphNode *node, int MII,
548 int maxASAP, MSchedGraphNode *srcNode) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000549
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000550 DEBUG(std::cerr << "Calculating ALAP for " << *node << "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000551
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000552 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
553
554 if(attributes.ALAP != -1)
555 return attributes.ALAP;
556
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000557 if(node->hasSuccessors()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000558
559 //Trying to deal with the issue where the node has successors, but
560 //we are ignoring all of the edges to them. So this is my hack for
561 //now.. there is probably a more elegant way of doing this (FIXME)
562 bool processedOneEdge = false;
563
564 //FIXME, set to something high to start
565 int minSuccValue = 9999999;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000566
567 //Iterate over all of the predecessors and fine max
568 for(MSchedGraphNode::succ_iterator P = node->succ_begin(),
569 E = node->succ_end(); P != E; ++P) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000570
571 //Only process if we are not ignoring the edge
572 if(!ignoreEdge(node, *P)) {
573 processedOneEdge = true;
574 int succALAP = -1;
575 succALAP = calculateALAP(*P, MII, maxASAP, node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000576
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000577 assert(succALAP != -1 && "Successors ALAP should have been caclulated");
578
579 int iteDiff = P.getEdge().getIteDiff();
580
581 int currentSuccValue = succALAP - node->getLatency() + iteDiff * MII;
582
583 DEBUG(std::cerr << "succ ALAP: " << succALAP << ", iteDiff: " << iteDiff << ", SuccLatency: " << (*P)->getLatency() << ", Current ALAP succ: " << currentSuccValue << "\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000584
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000585 minSuccValue = std::min(minSuccValue, currentSuccValue);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000586 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000587 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000588
589 if(processedOneEdge)
590 attributes.ALAP = minSuccValue;
591
592 else
593 attributes.ALAP = maxASAP;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000594 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000595 else
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000596 attributes.ALAP = maxASAP;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000597
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000598 DEBUG(std::cerr << "ALAP: " << attributes.ALAP << " (" << *node << ")\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000599
600 if(attributes.ALAP < 0)
601 attributes.ALAP = 0;
602
603 return attributes.ALAP;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000604}
605
606int ModuloSchedulingPass::findMaxASAP() {
607 int maxASAP = 0;
608
609 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(),
610 E = nodeToAttributesMap.end(); I != E; ++I)
611 maxASAP = std::max(maxASAP, I->second.ASAP);
612 return maxASAP;
613}
614
615
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000616int ModuloSchedulingPass::calculateHeight(MSchedGraphNode *node,MSchedGraphNode *srcNode) {
617
618 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000619
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000620 if(attributes.height != -1)
621 return attributes.height;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000622
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000623 int maxHeight = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000624
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000625 //Iterate over all of the predecessors and find max
626 for(MSchedGraphNode::succ_iterator P = node->succ_begin(),
627 E = node->succ_end(); P != E; ++P) {
628
629
630 if(!ignoreEdge(node, *P)) {
631 int succHeight = calculateHeight(*P, node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000632
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000633 assert(succHeight != -1 && "Successors Height should have been caclulated");
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000634
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000635 int currentHeight = succHeight + node->getLatency();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000636 maxHeight = std::max(maxHeight, currentHeight);
637 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000638 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000639 attributes.height = maxHeight;
640 DEBUG(std::cerr << "Height: " << attributes.height << " (" << *node << ")\n");
641 return maxHeight;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000642}
643
644
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000645int ModuloSchedulingPass::calculateDepth(MSchedGraphNode *node,
646 MSchedGraphNode *destNode) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000647
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000648 MSNodeAttributes &attributes = nodeToAttributesMap.find(node)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000649
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000650 if(attributes.depth != -1)
651 return attributes.depth;
652
653 int maxDepth = 0;
654
655 //Iterate over all of the predecessors and fine max
656 for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) {
657
658 if(!ignoreEdge(*P, node)) {
659 int predDepth = -1;
660 predDepth = calculateDepth(*P, node);
661
662 assert(predDepth != -1 && "Predecessors ASAP should have been caclulated");
663
664 int currentDepth = predDepth + (*P)->getLatency();
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000665 maxDepth = std::max(maxDepth, currentDepth);
666 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000667 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000668 attributes.depth = maxDepth;
669
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000670 DEBUG(std::cerr << "Depth: " << attributes.depth << " (" << *node << "*)\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000671 return maxDepth;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000672}
673
674
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000675
676void ModuloSchedulingPass::addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode *srcBENode, MSchedGraphNode *destBENode) {
677 //Check to make sure that this recurrence is unique
678 bool same = false;
679
680
681 //Loop over all recurrences already in our list
682 for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::iterator R = recurrenceList.begin(), RE = recurrenceList.end(); R != RE; ++R) {
683
684 bool all_same = true;
685 //First compare size
686 if(R->second.size() == recurrence.size()) {
687
688 for(std::vector<MSchedGraphNode*>::const_iterator node = R->second.begin(), end = R->second.end(); node != end; ++node) {
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +0000689 if(std::find(recurrence.begin(), recurrence.end(), *node) == recurrence.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000690 all_same = all_same && false;
691 break;
692 }
693 else
694 all_same = all_same && true;
695 }
696 if(all_same) {
697 same = true;
698 break;
699 }
700 }
701 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000702
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000703 if(!same) {
Tanya Lattner4cffb582004-05-26 06:27:18 +0000704 srcBENode = recurrence.back();
705 destBENode = recurrence.front();
706
707 //FIXME
708 if(destBENode->getInEdge(srcBENode).getIteDiff() == 0) {
709 //DEBUG(std::cerr << "NOT A BACKEDGE\n");
710 //find actual backedge HACK HACK
711 for(unsigned i=0; i< recurrence.size()-1; ++i) {
712 if(recurrence[i+1]->getInEdge(recurrence[i]).getIteDiff() == 1) {
713 srcBENode = recurrence[i];
714 destBENode = recurrence[i+1];
715 break;
716 }
717
718 }
719
720 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000721 DEBUG(std::cerr << "Back Edge to Remove: " << *srcBENode << " to " << *destBENode << "\n");
722 edgesToIgnore.insert(std::make_pair(srcBENode, destBENode->getInEdgeNum(srcBENode)));
723 recurrenceList.insert(std::make_pair(II, recurrence));
724 }
725
726}
727
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000728int CircCount;
729
730void ModuloSchedulingPass::unblock(MSchedGraphNode *u, std::set<MSchedGraphNode*> &blocked,
731 std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B) {
732
733 //Unblock u
734 DEBUG(std::cerr << "Unblocking: " << *u << "\n");
735 blocked.erase(u);
736
737 //std::set<MSchedGraphNode*> toErase;
738 while (!B[u].empty()) {
739 MSchedGraphNode *W = *B[u].begin();
740 B[u].erase(W);
741 //toErase.insert(*W);
742 DEBUG(std::cerr << "Removed: " << *W << "from B-List\n");
743 if(blocked.count(W))
744 unblock(W, blocked, B);
745 }
746
747}
748
749bool ModuloSchedulingPass::circuit(MSchedGraphNode *v, std::vector<MSchedGraphNode*> &stack,
750 std::set<MSchedGraphNode*> &blocked, std::vector<MSchedGraphNode*> &SCC,
751 MSchedGraphNode *s, std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B,
752 int II, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes) {
753 bool f = false;
754
755 DEBUG(std::cerr << "Finding Circuits Starting with: ( " << v << ")"<< *v << "\n");
756
757 //Push node onto the stack
758 stack.push_back(v);
759
760 //block this node
761 blocked.insert(v);
762
763 //Loop over all successors of node v that are in the scc, create Adjaceny list
764 std::set<MSchedGraphNode*> AkV;
765 for(MSchedGraphNode::succ_iterator I = v->succ_begin(), E = v->succ_end(); I != E; ++I) {
766 if((std::find(SCC.begin(), SCC.end(), *I) != SCC.end())) {
767 AkV.insert(*I);
768 }
769 }
770
771 for(std::set<MSchedGraphNode*>::iterator I = AkV.begin(), E = AkV.end(); I != E; ++I) {
772 if(*I == s) {
773 //We have a circuit, so add it to our list
774
775 std::vector<MSchedGraphNode*> recc;
776 //Dump recurrence for now
777 DEBUG(std::cerr << "Starting Recc\n");
778
779 int totalDelay = 0;
780 int totalDistance = 0;
781 MSchedGraphNode *lastN = 0;
782
783 //Loop over recurrence, get delay and distance
784 for(std::vector<MSchedGraphNode*>::iterator N = stack.begin(), NE = stack.end(); N != NE; ++N) {
785 totalDelay += (*N)->getLatency();
786 if(lastN) {
787 totalDistance += (*N)->getInEdge(lastN).getIteDiff();
788 }
789
790 //Get the original node
791 lastN = *N;
792 recc.push_back(newNodes[*N]);
793
794 DEBUG(std::cerr << *lastN << "\n");
795 }
796
797 //Get the loop edge
798 totalDistance += lastN->getIteDiff(*stack.begin());
799
800 DEBUG(std::cerr << "End Recc\n");
801 f = true;
802 CircCount++;
803
804 //Insert reccurrence into the list
805 DEBUG(std::cerr << "Ignore Edge from: " << *lastN << " to " << **stack.begin() << "\n");
806 edgesToIgnore.insert(std::make_pair(newNodes[lastN], newNodes[(*stack.begin())]->getInEdgeNum(newNodes[lastN])));
807
808 //Adjust II until we get close to the inequality delay - II*distance <= 0
809 int RecMII = II; //Starting value
810 int value = totalDelay-(RecMII * totalDistance);
811 int lastII = II;
812 while(value <= 0) {
813
814 lastII = RecMII;
815 RecMII--;
816 value = totalDelay-(RecMII * totalDistance);
817 }
818
819 recurrenceList.insert(std::make_pair(lastII, recc));
820
821 }
822 else if(!blocked.count(*I)) {
823 if(circuit(*I, stack, blocked, SCC, s, B, II, newNodes))
824 f = true;
825 }
826 else
827 DEBUG(std::cerr << "Blocked: " << **I << "\n");
828 }
829
830
831 if(f) {
832 unblock(v, blocked, B);
833 }
834 else {
835 for(std::set<MSchedGraphNode*>::iterator I = AkV.begin(), E = AkV.end(); I != E; ++I)
836 B[*I].insert(v);
837
838 }
839
840 //Pop v
841 stack.pop_back();
842
843 return f;
844
845}
846
847void ModuloSchedulingPass::findAllCircuits(MSchedGraph *g, int II) {
848
849 CircCount = 0;
850
851 //Keep old to new node mapping information
852 std::map<MSchedGraphNode*, MSchedGraphNode*> newNodes;
853
854 //copy the graph
855 MSchedGraph *MSG = new MSchedGraph(*g, newNodes);
856
857 DEBUG(std::cerr << "Finding All Circuits\n");
858
859 //Set of blocked nodes
860 std::set<MSchedGraphNode*> blocked;
861
862 //Stack holding current circuit
863 std::vector<MSchedGraphNode*> stack;
864
865 //Map for B Lists
866 std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > B;
867
868 //current node
869 MSchedGraphNode *s;
870
871
872 //Iterate over the graph until its down to one node or empty
873 while(MSG->size() > 1) {
874
875 //Write Graph out to file
876 //WriteGraphToFile(std::cerr, "Graph" + utostr(MSG->size()), MSG);
877
878 DEBUG(std::cerr << "Graph Size: " << MSG->size() << "\n");
879 DEBUG(std::cerr << "Finding strong component Vk with least vertex\n");
880
881 //Iterate over all the SCCs in the graph
882 std::set<MSchedGraphNode*> Visited;
883 std::vector<MSchedGraphNode*> Vk;
884 MSchedGraphNode* s = 0;
885
886 //Find scc with the least vertex
887 for (MSchedGraph::iterator GI = MSG->begin(), E = MSG->end(); GI != E; ++GI)
888 if (Visited.insert(GI->second).second) {
889 for (scc_iterator<MSchedGraphNode*> SCCI = scc_begin(GI->second),
890 E = scc_end(GI->second); SCCI != E; ++SCCI) {
891 std::vector<MSchedGraphNode*> &nextSCC = *SCCI;
892
893 if (Visited.insert(nextSCC[0]).second) {
894 Visited.insert(nextSCC.begin()+1, nextSCC.end());
895
896 DEBUG(std::cerr << "SCC size: " << nextSCC.size() << "\n");
897
898 //Ignore self loops
899 if(nextSCC.size() > 1) {
900
901 //Get least vertex in Vk
902 if(!s) {
903 s = nextSCC[0];
904 Vk = nextSCC;
905 }
906
907 for(unsigned i = 0; i < nextSCC.size(); ++i) {
908 if(nextSCC[i] < s) {
909 s = nextSCC[i];
910 Vk = nextSCC;
911 }
912 }
913 }
914 }
915 }
916 }
917
918
919
920 //Process SCC
921 DEBUG(for(std::vector<MSchedGraphNode*>::iterator N = Vk.begin(), NE = Vk.end();
922 N != NE; ++N) { std::cerr << *((*N)->getInst()); });
923
924 //Iterate over all nodes in this scc
925 for(std::vector<MSchedGraphNode*>::iterator N = Vk.begin(), NE = Vk.end();
926 N != NE; ++N) {
927 blocked.erase(*N);
928 B[*N].clear();
929 }
930 if(Vk.size() > 1) {
931 circuit(s, stack, blocked, Vk, s, B, II, newNodes);
932
933 //Find all nodes up to s and delete them
934 std::vector<MSchedGraphNode*> nodesToRemove;
935 nodesToRemove.push_back(s);
936 for(MSchedGraph::iterator N = MSG->begin(), NE = MSG->end(); N != NE; ++N) {
937 if(N->second < s )
938 nodesToRemove.push_back(N->second);
939 }
940 for(std::vector<MSchedGraphNode*>::iterator N = nodesToRemove.begin(), NE = nodesToRemove.end(); N != NE; ++N) {
941 DEBUG(std::cerr << "Deleting Node: " << **N << "\n");
942 MSG->deleteNode(*N);
943 }
944 }
945 else
946 break;
947 }
948 DEBUG(std::cerr << "Num Circuits found: " << CircCount << "\n");
949}
950
951
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000952void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node,
953 std::vector<MSchedGraphNode*> &visitedNodes,
954 int II) {
Tanya Lattnerdb40cf12005-02-10 17:02:58 +0000955
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000956
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +0000957 if(std::find(visitedNodes.begin(), visitedNodes.end(), node) != visitedNodes.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000958 std::vector<MSchedGraphNode*> recurrence;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000959 bool first = true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000960 int delay = 0;
961 int distance = 0;
962 int RecMII = II; //Starting value
963 MSchedGraphNode *last = node;
Chris Lattner46c2b3a2004-08-04 03:51:55 +0000964 MSchedGraphNode *srcBackEdge = 0;
965 MSchedGraphNode *destBackEdge = 0;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000966
967
968
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000969 for(std::vector<MSchedGraphNode*>::iterator I = visitedNodes.begin(), E = visitedNodes.end();
970 I !=E; ++I) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000971
972 if(*I == node)
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000973 first = false;
974 if(first)
975 continue;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000976
977 delay = delay + (*I)->getLatency();
978
979 if(*I != node) {
980 int diff = (*I)->getInEdge(last).getIteDiff();
981 distance += diff;
982 if(diff > 0) {
983 srcBackEdge = last;
984 destBackEdge = *I;
985 }
986 }
987
988 recurrence.push_back(*I);
989 last = *I;
Tanya Lattnerd14b8372004-03-01 02:50:01 +0000990 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000991
992
993
994 //Get final distance calc
995 distance += node->getInEdge(last).getIteDiff();
Tanya Lattnere1df2122004-11-22 20:41:24 +0000996 DEBUG(std::cerr << "Reccurrence Distance: " << distance << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +0000997
998 //Adjust II until we get close to the inequality delay - II*distance <= 0
999
1000 int value = delay-(RecMII * distance);
1001 int lastII = II;
1002 while(value <= 0) {
1003
1004 lastII = RecMII;
1005 RecMII--;
1006 value = delay-(RecMII * distance);
1007 }
1008
1009
1010 DEBUG(std::cerr << "Final II for this recurrence: " << lastII << "\n");
1011 addReccurrence(recurrence, lastII, srcBackEdge, destBackEdge);
1012 assert(distance != 0 && "Recurrence distance should not be zero");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001013 return;
1014 }
1015
Tanya Lattner01114742005-01-18 04:15:41 +00001016 unsigned count = 0;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001017 for(MSchedGraphNode::succ_iterator I = node->succ_begin(), E = node->succ_end(); I != E; ++I) {
1018 visitedNodes.push_back(node);
Tanya Lattner01114742005-01-18 04:15:41 +00001019 //if(!edgesToIgnore.count(std::make_pair(node, count)))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001020 findAllReccurrences(*I, visitedNodes, II);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001021 visitedNodes.pop_back();
Tanya Lattner01114742005-01-18 04:15:41 +00001022 count++;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001023 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001024}
1025
1026
1027
1028
1029
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001030void ModuloSchedulingPass::computePartialOrder() {
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001031
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001032 TIME_REGION(X, "calculatePartialOrder");
1033
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001034 //Only push BA branches onto the final node order, we put other branches after it
1035 //FIXME: Should we really be pushing branches on it a specific order instead of relying
1036 //on BA being there?
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001037 std::vector<MSchedGraphNode*> branches;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001038
1039 //Loop over all recurrences and add to our partial order
1040 //be sure to remove nodes that are already in the partial order in
1041 //a different recurrence and don't add empty recurrences.
1042 for(std::set<std::pair<int, std::vector<MSchedGraphNode*> > >::reverse_iterator I = recurrenceList.rbegin(), E=recurrenceList.rend(); I !=E; ++I) {
1043
1044 //Add nodes that connect this recurrence to the previous recurrence
1045
1046 //If this is the first recurrence in the partial order, add all predecessors
1047 for(std::vector<MSchedGraphNode*>::const_iterator N = I->second.begin(), NE = I->second.end(); N != NE; ++N) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001048
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001049 }
1050
1051
Tanya Lattner260652a2004-10-30 00:39:07 +00001052 std::set<MSchedGraphNode*> new_recurrence;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001053 //Loop through recurrence and remove any nodes already in the partial order
1054 for(std::vector<MSchedGraphNode*>::const_iterator N = I->second.begin(), NE = I->second.end(); N != NE; ++N) {
1055 bool found = false;
Tanya Lattner260652a2004-10-30 00:39:07 +00001056 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(), PE = partialOrder.end(); PO != PE; ++PO) {
1057 if(PO->count(*N))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001058 found = true;
1059 }
1060 if(!found) {
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001061 if((*N)->isBranch()) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001062 branches.push_back(*N);
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001063 }
1064 else
1065 new_recurrence.insert(*N);
1066 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001067 if(partialOrder.size() == 0)
1068 //For each predecessors, add it to this recurrence ONLY if it is not already in it
1069 for(MSchedGraphNode::pred_iterator P = (*N)->pred_begin(),
1070 PE = (*N)->pred_end(); P != PE; ++P) {
1071
1072 //Check if we are supposed to ignore this edge or not
1073 if(!ignoreEdge(*P, *N))
1074 //Check if already in this recurrence
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001075 if(std::find(I->second.begin(), I->second.end(), *P) == I->second.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001076 //Also need to check if in partial order
1077 bool predFound = false;
Tanya Lattner260652a2004-10-30 00:39:07 +00001078 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(), PEND = partialOrder.end(); PO != PEND; ++PO) {
1079 if(PO->count(*P))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001080 predFound = true;
1081 }
1082
1083 if(!predFound)
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001084 if(!new_recurrence.count(*P)) {
1085 if((*P)->isBranch()) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001086 branches.push_back(*P);
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001087 }
1088 else
1089 new_recurrence.insert(*P);
1090
1091 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001092 }
1093 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001094 }
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001095
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001096 if(new_recurrence.size() > 0)
1097 partialOrder.push_back(new_recurrence);
1098 }
1099
1100 //Add any nodes that are not already in the partial order
Tanya Lattner260652a2004-10-30 00:39:07 +00001101 //Add them in a set, one set per connected component
1102 std::set<MSchedGraphNode*> lastNodes;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001103 for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) {
1104 bool found = false;
1105 //Check if its already in our partial order, if not add it to the final vector
Tanya Lattner260652a2004-10-30 00:39:07 +00001106 for(std::vector<std::set<MSchedGraphNode*> >::iterator PO = partialOrder.begin(), PE = partialOrder.end(); PO != PE; ++PO) {
1107 if(PO->count(I->first))
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001108 found = true;
1109 }
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001110 if(!found) {
1111 if(I->first->isBranch()) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001112 if(std::find(branches.begin(), branches.end(), I->first) == branches.end())
1113 branches.push_back(I->first);
1114 }
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001115 else
1116 lastNodes.insert(I->first);
1117 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001118 }
1119
Tanya Lattner260652a2004-10-30 00:39:07 +00001120 //Break up remaining nodes that are not in the partial order
1121 //into their connected compoenents
1122 while(lastNodes.size() > 0) {
1123 std::set<MSchedGraphNode*> ccSet;
1124 connectedComponentSet(*(lastNodes.begin()),ccSet, lastNodes);
1125 if(ccSet.size() > 0)
1126 partialOrder.push_back(ccSet);
1127 }
1128 //if(lastNodes.size() > 0)
1129 //partialOrder.push_back(lastNodes);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001130
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001131 //Clean up branches by putting them in final order
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001132 std::map<unsigned, MSchedGraphNode*> branchOrder;
1133 for(std::vector<MSchedGraphNode*>::iterator I = branches.begin(), E = branches.end(); I != E; ++I)
1134 branchOrder[(*I)->getIndex()] = *I;
1135
1136 for(std::map<unsigned, MSchedGraphNode*>::reverse_iterator I = branchOrder.rbegin(), E = branchOrder.rend(); I != E; ++I)
1137 FinalNodeOrder.push_back(I->second);
1138
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001139}
1140
1141
Tanya Lattner260652a2004-10-30 00:39:07 +00001142void ModuloSchedulingPass::connectedComponentSet(MSchedGraphNode *node, std::set<MSchedGraphNode*> &ccSet, std::set<MSchedGraphNode*> &lastNodes) {
1143
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001144//Add to final set
1145if( !ccSet.count(node) && lastNodes.count(node)) {
Tanya Lattner260652a2004-10-30 00:39:07 +00001146 lastNodes.erase(node);
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001147if(node->isBranch())
1148 FinalNodeOrder.push_back(node);
1149 else
1150 ccSet.insert(node);
Tanya Lattner260652a2004-10-30 00:39:07 +00001151 }
1152 else
1153 return;
1154
1155 //Loop over successors and recurse if we have not seen this node before
1156 for(MSchedGraphNode::succ_iterator node_succ = node->succ_begin(), end=node->succ_end(); node_succ != end; ++node_succ) {
1157 connectedComponentSet(*node_succ, ccSet, lastNodes);
1158 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001159
Tanya Lattner260652a2004-10-30 00:39:07 +00001160}
1161
1162void ModuloSchedulingPass::predIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001163
1164 for(unsigned j=0; j < FinalNodeOrder.size(); ++j) {
1165 for(MSchedGraphNode::pred_iterator P = FinalNodeOrder[j]->pred_begin(),
1166 E = FinalNodeOrder[j]->pred_end(); P != E; ++P) {
1167
1168 //Check if we are supposed to ignore this edge or not
1169 if(ignoreEdge(*P,FinalNodeOrder[j]))
1170 continue;
1171
Tanya Lattner260652a2004-10-30 00:39:07 +00001172 if(CurrentSet.count(*P))
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001173 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end())
Tanya Lattner260652a2004-10-30 00:39:07 +00001174 IntersectResult.insert(*P);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001175 }
1176 }
1177}
1178
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001179
Tanya Lattner260652a2004-10-30 00:39:07 +00001180
1181
1182
1183void ModuloSchedulingPass::succIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult) {
1184
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001185 for(unsigned j=0; j < FinalNodeOrder.size(); ++j) {
1186 for(MSchedGraphNode::succ_iterator P = FinalNodeOrder[j]->succ_begin(),
1187 E = FinalNodeOrder[j]->succ_end(); P != E; ++P) {
1188
1189 //Check if we are supposed to ignore this edge or not
1190 if(ignoreEdge(FinalNodeOrder[j],*P))
1191 continue;
1192
Tanya Lattner260652a2004-10-30 00:39:07 +00001193 if(CurrentSet.count(*P))
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001194 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), *P) == FinalNodeOrder.end())
Tanya Lattner260652a2004-10-30 00:39:07 +00001195 IntersectResult.insert(*P);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001196 }
1197 }
1198}
1199
Tanya Lattner260652a2004-10-30 00:39:07 +00001200void dumpIntersection(std::set<MSchedGraphNode*> &IntersectCurrent) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001201 std::cerr << "Intersection (";
Tanya Lattner260652a2004-10-30 00:39:07 +00001202 for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(), E = IntersectCurrent.end(); I != E; ++I)
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001203 std::cerr << **I << ", ";
1204 std::cerr << ")\n";
1205}
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001206
1207
1208
1209void ModuloSchedulingPass::orderNodes() {
1210
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001211 TIME_REGION(X, "orderNodes");
1212
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001213 int BOTTOM_UP = 0;
1214 int TOP_DOWN = 1;
1215
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001216 //Set default order
1217 int order = BOTTOM_UP;
1218
Tanya Lattnera6ec8f52004-11-24 01:49:10 +00001219
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001220 //Loop over all the sets and place them in the final node order
Tanya Lattner260652a2004-10-30 00:39:07 +00001221 for(std::vector<std::set<MSchedGraphNode*> >::iterator CurrentSet = partialOrder.begin(), E= partialOrder.end(); CurrentSet != E; ++CurrentSet) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001222
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001223 DEBUG(std::cerr << "Processing set in S\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001224 DEBUG(dumpIntersection(*CurrentSet));
1225
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001226 //Result of intersection
Tanya Lattner260652a2004-10-30 00:39:07 +00001227 std::set<MSchedGraphNode*> IntersectCurrent;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001228
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001229 predIntersect(*CurrentSet, IntersectCurrent);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001230
1231 //If the intersection of predecessor and current set is not empty
1232 //sort nodes bottom up
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001233 if(IntersectCurrent.size() != 0) {
1234 DEBUG(std::cerr << "Final Node Order Predecessors and Current Set interesection is NOT empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001235 order = BOTTOM_UP;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001236 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001237 //If empty, use successors
1238 else {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001239 DEBUG(std::cerr << "Final Node Order Predecessors and Current Set interesection is empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001240
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001241 succIntersect(*CurrentSet, IntersectCurrent);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001242
1243 //sort top-down
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001244 if(IntersectCurrent.size() != 0) {
1245 DEBUG(std::cerr << "Final Node Order Successors and Current Set interesection is NOT empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001246 order = TOP_DOWN;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001247 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001248 else {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001249 DEBUG(std::cerr << "Final Node Order Successors and Current Set interesection is empty\n");
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001250 //Find node with max ASAP in current Set
1251 MSchedGraphNode *node;
1252 int maxASAP = 0;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001253 DEBUG(std::cerr << "Using current set of size " << CurrentSet->size() << "to find max ASAP\n");
Tanya Lattner260652a2004-10-30 00:39:07 +00001254 for(std::set<MSchedGraphNode*>::iterator J = CurrentSet->begin(), JE = CurrentSet->end(); J != JE; ++J) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001255 //Get node attributes
Tanya Lattner260652a2004-10-30 00:39:07 +00001256 MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*J)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001257 //assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!");
Tanya Lattner260652a2004-10-30 00:39:07 +00001258
1259 if(maxASAP <= nodeAttr.ASAP) {
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001260 maxASAP = nodeAttr.ASAP;
Tanya Lattner260652a2004-10-30 00:39:07 +00001261 node = *J;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001262 }
1263 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001264 assert(node != 0 && "In node ordering node should not be null");
Tanya Lattner260652a2004-10-30 00:39:07 +00001265 IntersectCurrent.insert(node);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001266 order = BOTTOM_UP;
1267 }
1268 }
1269
1270 //Repeat until all nodes are put into the final order from current set
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001271 while(IntersectCurrent.size() > 0) {
1272
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001273 if(order == TOP_DOWN) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001274 DEBUG(std::cerr << "Order is TOP DOWN\n");
1275
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001276 while(IntersectCurrent.size() > 0) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001277 DEBUG(std::cerr << "Intersection is not empty, so find heighest height\n");
1278
1279 int MOB = 0;
1280 int height = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001281 MSchedGraphNode *highestHeightNode = *(IntersectCurrent.begin());
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001282
1283 //Find node in intersection with highest heigh and lowest MOB
Tanya Lattner260652a2004-10-30 00:39:07 +00001284 for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(),
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001285 E = IntersectCurrent.end(); I != E; ++I) {
1286
1287 //Get current nodes properties
1288 MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001289
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001290 if(height < nodeAttr.height) {
1291 highestHeightNode = *I;
1292 height = nodeAttr.height;
1293 MOB = nodeAttr.MOB;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001294 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001295 else if(height == nodeAttr.height) {
1296 if(MOB > nodeAttr.height) {
1297 highestHeightNode = *I;
1298 height = nodeAttr.height;
1299 MOB = nodeAttr.MOB;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001300 }
1301 }
1302 }
1303
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001304 //Append our node with greatest height to the NodeOrder
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001305 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestHeightNode) == FinalNodeOrder.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001306 DEBUG(std::cerr << "Adding node to Final Order: " << *highestHeightNode << "\n");
1307 FinalNodeOrder.push_back(highestHeightNode);
1308 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001309
1310 //Remove V from IntersectOrder
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001311 IntersectCurrent.erase(std::find(IntersectCurrent.begin(),
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001312 IntersectCurrent.end(), highestHeightNode));
1313
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001314
1315 //Intersect V's successors with CurrentSet
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001316 for(MSchedGraphNode::succ_iterator P = highestHeightNode->succ_begin(),
1317 E = highestHeightNode->succ_end(); P != E; ++P) {
1318 //if(lower_bound(CurrentSet->begin(),
1319 // CurrentSet->end(), *P) != CurrentSet->end()) {
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001320 if(std::find(CurrentSet->begin(), CurrentSet->end(), *P) != CurrentSet->end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001321 if(ignoreEdge(highestHeightNode, *P))
1322 continue;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001323 //If not already in Intersect, add
Tanya Lattner260652a2004-10-30 00:39:07 +00001324 if(!IntersectCurrent.count(*P))
1325 IntersectCurrent.insert(*P);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001326 }
1327 }
1328 } //End while loop over Intersect Size
1329
1330 //Change direction
1331 order = BOTTOM_UP;
1332
1333 //Reset Intersect to reflect changes in OrderNodes
1334 IntersectCurrent.clear();
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001335 predIntersect(*CurrentSet, IntersectCurrent);
1336
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001337 } //End If TOP_DOWN
1338
1339 //Begin if BOTTOM_UP
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001340 else {
1341 DEBUG(std::cerr << "Order is BOTTOM UP\n");
1342 while(IntersectCurrent.size() > 0) {
1343 DEBUG(std::cerr << "Intersection of size " << IntersectCurrent.size() << ", finding highest depth\n");
1344
1345 //dump intersection
1346 DEBUG(dumpIntersection(IntersectCurrent));
1347 //Get node with highest depth, if a tie, use one with lowest
1348 //MOB
1349 int MOB = 0;
1350 int depth = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001351 MSchedGraphNode *highestDepthNode = *(IntersectCurrent.begin());
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001352
Tanya Lattner260652a2004-10-30 00:39:07 +00001353 for(std::set<MSchedGraphNode*>::iterator I = IntersectCurrent.begin(),
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001354 E = IntersectCurrent.end(); I != E; ++I) {
1355 //Find node attribute in graph
1356 MSNodeAttributes nodeAttr= nodeToAttributesMap.find(*I)->second;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001357
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001358 if(depth < nodeAttr.depth) {
1359 highestDepthNode = *I;
1360 depth = nodeAttr.depth;
1361 MOB = nodeAttr.MOB;
1362 }
1363 else if(depth == nodeAttr.depth) {
1364 if(MOB > nodeAttr.MOB) {
1365 highestDepthNode = *I;
1366 depth = nodeAttr.depth;
1367 MOB = nodeAttr.MOB;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001368 }
1369 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001370 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001371
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001372
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001373
1374 //Append highest depth node to the NodeOrder
Alkis Evlogimenosc72c6172004-09-28 14:42:44 +00001375 if(std::find(FinalNodeOrder.begin(), FinalNodeOrder.end(), highestDepthNode) == FinalNodeOrder.end()) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001376 DEBUG(std::cerr << "Adding node to Final Order: " << *highestDepthNode << "\n");
1377 FinalNodeOrder.push_back(highestDepthNode);
1378 }
1379 //Remove heightestDepthNode from IntersectOrder
Tanya Lattner260652a2004-10-30 00:39:07 +00001380 IntersectCurrent.erase(highestDepthNode);
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001381
1382
1383 //Intersect heightDepthNode's pred with CurrentSet
1384 for(MSchedGraphNode::pred_iterator P = highestDepthNode->pred_begin(),
1385 E = highestDepthNode->pred_end(); P != E; ++P) {
Tanya Lattner260652a2004-10-30 00:39:07 +00001386 if(CurrentSet->count(*P)) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001387 if(ignoreEdge(*P, highestDepthNode))
1388 continue;
1389
1390 //If not already in Intersect, add
Tanya Lattner260652a2004-10-30 00:39:07 +00001391 if(!IntersectCurrent.count(*P))
1392 IntersectCurrent.insert(*P);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001393 }
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001394 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001395
1396 } //End while loop over Intersect Size
1397
1398 //Change order
1399 order = TOP_DOWN;
1400
1401 //Reset IntersectCurrent to reflect changes in OrderNodes
1402 IntersectCurrent.clear();
1403 succIntersect(*CurrentSet, IntersectCurrent);
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001404 } //End if BOTTOM_DOWN
1405
Tanya Lattner420025b2004-10-10 22:44:35 +00001406 DEBUG(std::cerr << "Current Intersection Size: " << IntersectCurrent.size() << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001407 }
1408 //End Wrapping while loop
Tanya Lattner420025b2004-10-10 22:44:35 +00001409 DEBUG(std::cerr << "Ending Size of Current Set: " << CurrentSet->size() << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001410 }//End for over all sets of nodes
Tanya Lattner420025b2004-10-10 22:44:35 +00001411
1412 //FIXME: As the algorithm stands it will NEVER add an instruction such as ba (with no
1413 //data dependencies) to the final order. We add this manually. It will always be
1414 //in the last set of S since its not part of a recurrence
1415 //Loop over all the sets and place them in the final node order
Tanya Lattner260652a2004-10-30 00:39:07 +00001416 std::vector<std::set<MSchedGraphNode*> > ::reverse_iterator LastSet = partialOrder.rbegin();
1417 for(std::set<MSchedGraphNode*>::iterator CurrentNode = LastSet->begin(), LastNode = LastSet->end();
Tanya Lattner420025b2004-10-10 22:44:35 +00001418 CurrentNode != LastNode; ++CurrentNode) {
1419 if((*CurrentNode)->getInst()->getOpcode() == V9::BA)
1420 FinalNodeOrder.push_back(*CurrentNode);
1421 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001422 //Return final Order
1423 //return FinalNodeOrder;
1424}
1425
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001426bool ModuloSchedulingPass::computeSchedule() {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001427
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00001428 TIME_REGION(X, "computeSchedule");
1429
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001430 bool success = false;
1431
Tanya Lattner260652a2004-10-30 00:39:07 +00001432 //FIXME: Should be set to max II of the original loop
1433 //Cap II in order to prevent infinite loop
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001434 int capII = 100;
Tanya Lattner260652a2004-10-30 00:39:07 +00001435
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001436 while(!success) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001437
1438 int branchES = II - 1;
1439 int branchLS = II - 1;
1440 bool lastBranch = true;
1441
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001442 //Loop over the final node order and process each node
1443 for(std::vector<MSchedGraphNode*>::iterator I = FinalNodeOrder.begin(),
1444 E = FinalNodeOrder.end(); I != E; ++I) {
1445
1446 //CalculateEarly and Late start
1447 int EarlyStart = -1;
1448 int LateStart = 99999; //Set to something higher then we would ever expect (FIXME)
1449 bool hasSucc = false;
1450 bool hasPred = false;
Tanya Lattner4cffb582004-05-26 06:27:18 +00001451
1452 if(!(*I)->isBranch()) {
1453 //Loop over nodes in the schedule and determine if they are predecessors
1454 //or successors of the node we are trying to schedule
1455 for(MSSchedule::schedule_iterator nodesByCycle = schedule.begin(), nodesByCycleEnd = schedule.end();
1456 nodesByCycle != nodesByCycleEnd; ++nodesByCycle) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001457
Tanya Lattner4cffb582004-05-26 06:27:18 +00001458 //For this cycle, get the vector of nodes schedule and loop over it
1459 for(std::vector<MSchedGraphNode*>::iterator schedNode = nodesByCycle->second.begin(), SNE = nodesByCycle->second.end(); schedNode != SNE; ++schedNode) {
1460
1461 if((*I)->isPredecessor(*schedNode)) {
Tanya Lattner01114742005-01-18 04:15:41 +00001462 //if(!ignoreEdge(*schedNode, *I)) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001463 int diff = (*I)->getInEdge(*schedNode).getIteDiff();
Tanya Lattner4cffb582004-05-26 06:27:18 +00001464 int ES_Temp = nodesByCycle->first + (*schedNode)->getLatency() - diff * II;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001465 DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001466 DEBUG(std::cerr << "Temp EarlyStart: " << ES_Temp << " Prev EarlyStart: " << EarlyStart << "\n");
1467 EarlyStart = std::max(EarlyStart, ES_Temp);
1468 hasPred = true;
Tanya Lattner01114742005-01-18 04:15:41 +00001469 //}
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001470 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001471 if((*I)->isSuccessor(*schedNode)) {
Tanya Lattner01114742005-01-18 04:15:41 +00001472 //if(!ignoreEdge(*I,*schedNode)) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001473 int diff = (*schedNode)->getInEdge(*I).getIteDiff();
Tanya Lattner4cffb582004-05-26 06:27:18 +00001474 int LS_Temp = nodesByCycle->first - (*I)->getLatency() + diff * II;
1475 DEBUG(std::cerr << "Diff: " << diff << " Cycle: " << nodesByCycle->first << "\n");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001476 DEBUG(std::cerr << "Temp LateStart: " << LS_Temp << " Prev LateStart: " << LateStart << "\n");
1477 LateStart = std::min(LateStart, LS_Temp);
1478 hasSucc = true;
Tanya Lattner01114742005-01-18 04:15:41 +00001479 //}
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001480 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001481 }
1482 }
1483 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001484 else {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001485 if(lastBranch) {
1486 EarlyStart = branchES;
1487 LateStart = branchLS;
1488 lastBranch = false;
1489 --branchES;
1490 branchLS = 0;
Tanya Lattner420025b2004-10-10 22:44:35 +00001491 }
1492 else {
Tanya Lattner01114742005-01-18 04:15:41 +00001493 EarlyStart = branchLS;
1494 LateStart = branchES;
Tanya Lattner420025b2004-10-10 22:44:35 +00001495 assert( (EarlyStart >= 0) && (LateStart >=0) && "EarlyStart and LateStart must be greater then 0");
Tanya Lattner58fe2f02004-11-29 04:39:47 +00001496 --branchES;
Tanya Lattner420025b2004-10-10 22:44:35 +00001497 }
Tanya Lattner01114742005-01-18 04:15:41 +00001498 hasPred = 0;
Tanya Lattner4cffb582004-05-26 06:27:18 +00001499 hasSucc = 1;
1500 }
1501
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001502 DEBUG(std::cerr << "Has Successors: " << hasSucc << ", Has Pred: " << hasPred << "\n");
1503 DEBUG(std::cerr << "EarlyStart: " << EarlyStart << ", LateStart: " << LateStart << "\n");
1504
Tanya Lattner01114742005-01-18 04:15:41 +00001505
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001506 //Check if the node has no pred or successors and set Early Start to its ASAP
1507 if(!hasSucc && !hasPred)
1508 EarlyStart = nodeToAttributesMap.find(*I)->second.ASAP;
1509
1510 //Now, try to schedule this node depending upon its pred and successor in the schedule
1511 //already
1512 if(!hasSucc && hasPred)
1513 success = scheduleNode(*I, EarlyStart, (EarlyStart + II -1));
1514 else if(!hasPred && hasSucc)
1515 success = scheduleNode(*I, LateStart, (LateStart - II +1));
Tanya Lattner01114742005-01-18 04:15:41 +00001516 else if(hasPred && hasSucc) {
1517 if(EarlyStart > LateStart)
1518 success = false;
1519 else
1520 success = scheduleNode(*I, EarlyStart, std::min(LateStart, (EarlyStart + II -1)));
1521 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001522 else
1523 success = scheduleNode(*I, EarlyStart, EarlyStart + II - 1);
1524
1525 if(!success) {
Tanya Lattnere1df2122004-11-22 20:41:24 +00001526 ++IncreasedII;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001527 ++II;
1528 schedule.clear();
1529 break;
1530 }
1531
1532 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001533
Tanya Lattner260652a2004-10-30 00:39:07 +00001534 if(success) {
1535 DEBUG(std::cerr << "Constructing Schedule Kernel\n");
1536 success = schedule.constructKernel(II);
1537 DEBUG(std::cerr << "Done Constructing Schedule Kernel\n");
1538 if(!success) {
Tanya Lattnere1df2122004-11-22 20:41:24 +00001539 ++IncreasedII;
Tanya Lattner260652a2004-10-30 00:39:07 +00001540 ++II;
1541 schedule.clear();
1542 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001543 }
Tanya Lattner260652a2004-10-30 00:39:07 +00001544
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001545 if(II >= capII)
1546 return false;
1547
Tanya Lattner260652a2004-10-30 00:39:07 +00001548 assert(II < capII && "The II should not exceed the original loop number of cycles");
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001549 }
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001550 return true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001551}
1552
1553
1554bool ModuloSchedulingPass::scheduleNode(MSchedGraphNode *node,
1555 int start, int end) {
1556 bool success = false;
1557
1558 DEBUG(std::cerr << *node << " (Start Cycle: " << start << ", End Cycle: " << end << ")\n");
1559
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001560 //Make sure start and end are not negative
Tanya Lattner260652a2004-10-30 00:39:07 +00001561 if(start < 0) {
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001562 start = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001563
1564 }
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001565 if(end < 0)
1566 end = 0;
1567
1568 bool forward = true;
1569 if(start > end)
1570 forward = false;
1571
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001572 bool increaseSC = true;
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001573 int cycle = start ;
1574
1575
1576 while(increaseSC) {
1577
1578 increaseSC = false;
1579
Tanya Lattner4cffb582004-05-26 06:27:18 +00001580 increaseSC = schedule.insert(node, cycle);
1581
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001582 if(!increaseSC)
1583 return true;
1584
1585 //Increment cycle to try again
1586 if(forward) {
1587 ++cycle;
1588 DEBUG(std::cerr << "Increase cycle: " << cycle << "\n");
1589 if(cycle > end)
1590 return false;
1591 }
1592 else {
1593 --cycle;
1594 DEBUG(std::cerr << "Decrease cycle: " << cycle << "\n");
1595 if(cycle < end)
1596 return false;
1597 }
1598 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001599
Tanya Lattner73e3e2e2004-05-08 16:12:10 +00001600 return success;
Tanya Lattnerd14b8372004-03-01 02:50:01 +00001601}
Tanya Lattner4cffb582004-05-26 06:27:18 +00001602
Tanya Lattner420025b2004-10-10 22:44:35 +00001603void ModuloSchedulingPass::writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MSchedGraphNode*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00001604
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001605 //Keep a map to easily know whats in the kernel
Tanya Lattner4cffb582004-05-26 06:27:18 +00001606 std::map<int, std::set<const MachineInstr*> > inKernel;
1607 int maxStageCount = 0;
1608
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001609 //Keep a map of new values we consumed in case they need to be added back
1610 std::map<Value*, std::map<int, Value*> > consumedValues;
1611
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001612 MSchedGraphNode *branch = 0;
Tanya Lattner260652a2004-10-30 00:39:07 +00001613 MSchedGraphNode *BAbranch = 0;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001614
Tanya Lattnere1df2122004-11-22 20:41:24 +00001615 schedule.print(std::cerr);
1616
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001617 std::vector<MSchedGraphNode*> branches;
1618
Tanya Lattner4cffb582004-05-26 06:27:18 +00001619 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
1620 maxStageCount = std::max(maxStageCount, I->second);
1621
1622 //Ignore the branch, we will handle this separately
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001623 if(I->first->isBranch()) {
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001624 branches.push_back(I->first);
Tanya Lattner4cffb582004-05-26 06:27:18 +00001625 continue;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001626 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001627
1628 //Put int the map so we know what instructions in each stage are in the kernel
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001629 DEBUG(std::cerr << "Inserting instruction " << *(I->first->getInst()) << " into map at stage " << I->second << "\n");
1630 inKernel[I->second].insert(I->first->getInst());
Tanya Lattner4cffb582004-05-26 06:27:18 +00001631 }
1632
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001633 //Get target information to look at machine operands
1634 const TargetInstrInfo *mii = target.getInstrInfo();
1635
1636 //Now write the prologues
1637 for(int i = 0; i < maxStageCount; ++i) {
1638 BasicBlock *llvmBB = new BasicBlock("PROLOGUE", (Function*) (origBB->getBasicBlock()->getParent()));
Tanya Lattner4cffb582004-05-26 06:27:18 +00001639 MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB);
1640
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001641 DEBUG(std::cerr << "i=" << i << "\n");
1642 for(int j = 0; j <= i; ++j) {
1643 for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
1644 if(inKernel[j].count(&*MI)) {
Tanya Lattner420025b2004-10-10 22:44:35 +00001645 MachineInstr *instClone = MI->clone();
1646 machineBB->push_back(instClone);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001647
Tanya Lattner420025b2004-10-10 22:44:35 +00001648 DEBUG(std::cerr << "Cloning: " << *MI << "\n");
1649
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001650 Instruction *tmp;
1651
1652 //After cloning, we may need to save the value that this instruction defines
1653 for(unsigned opNum=0; opNum < MI->getNumOperands(); ++opNum) {
1654 //get machine operand
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001655 MachineOperand &mOp = instClone->getOperand(opNum);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001656 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
1657
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001658 //Check if this is a value we should save
1659 if(valuesToSave.count(mOp.getVRegValue())) {
1660 //Save copy in tmpInstruction
1661 tmp = new TmpInstruction(mOp.getVRegValue());
1662
Tanya Lattner80f08552004-11-02 21:04:56 +00001663 //Add TmpInstruction to safe LLVM Instruction MCFI
1664 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00001665 tempMvec.addTemp((Value*) tmp);
1666
Tanya Lattner420025b2004-10-10 22:44:35 +00001667 DEBUG(std::cerr << "Value: " << *(mOp.getVRegValue()) << " New Value: " << *tmp << " Stage: " << i << "\n");
1668
1669 newValues[mOp.getVRegValue()][i]= tmp;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001670 newValLocation[tmp] = machineBB;
1671
Tanya Lattner420025b2004-10-10 22:44:35 +00001672 DEBUG(std::cerr << "Machine Instr Operands: " << *(mOp.getVRegValue()) << ", 0, " << *tmp << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001673
1674 //Create machine instruction and put int machineBB
1675 MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
1676
1677 DEBUG(std::cerr << "Created new machine instr: " << *saveValue << "\n");
1678 }
1679 }
Tanya Lattner420025b2004-10-10 22:44:35 +00001680
1681 //We may also need to update the value that we use if its from an earlier prologue
1682 if(j != 0) {
1683 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001684 if(newValues.count(mOp.getVRegValue())) {
1685 if(newValues[mOp.getVRegValue()].count(i-1)) {
1686 Value *oldV = mOp.getVRegValue();
Tanya Lattner420025b2004-10-10 22:44:35 +00001687 DEBUG(std::cerr << "Replaced this value: " << mOp.getVRegValue() << " With:" << (newValues[mOp.getVRegValue()][i-1]) << "\n");
1688 //Update the operand with the right value
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001689 mOp.setValueReg(newValues[mOp.getVRegValue()][i-1]);
1690
1691 //Remove this value since we have consumed it
1692 //NOTE: Should this only be done if j != maxStage?
1693 consumedValues[oldV][i-1] = (newValues[oldV][i-1]);
1694 DEBUG(std::cerr << "Deleted value: " << consumedValues[oldV][i-1] << "\n");
1695 newValues[oldV].erase(i-1);
Tanya Lattner420025b2004-10-10 22:44:35 +00001696 }
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001697 }
1698 else
1699 if(consumedValues.count(mOp.getVRegValue()))
1700 assert(!consumedValues[mOp.getVRegValue()].count(i-1) && "Found a case where we need the value");
Tanya Lattner420025b2004-10-10 22:44:35 +00001701 }
1702 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001703 }
1704 }
Tanya Lattner20890832004-05-28 20:14:12 +00001705 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00001706 }
1707
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001708
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001709 for(std::vector<MSchedGraphNode*>::iterator BR = branches.begin(), BE = branches.end(); BR != BE; ++BR) {
1710
1711 //Stick in branch at the end
1712 machineBB->push_back((*BR)->getInst()->clone());
Tanya Lattner260652a2004-10-30 00:39:07 +00001713
Tanya Lattnerad7654f2004-12-02 07:22:15 +00001714 //Add nop
1715 BuildMI(machineBB, V9::NOP, 0);
1716 }
Tanya Lattner260652a2004-10-30 00:39:07 +00001717
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001718
1719 (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
Tanya Lattner4cffb582004-05-26 06:27:18 +00001720 prologues.push_back(machineBB);
1721 llvm_prologues.push_back(llvmBB);
1722 }
1723}
1724
Tanya Lattner420025b2004-10-10 22:44:35 +00001725void ModuloSchedulingPass::writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MSchedGraphNode*, 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 +00001726
Tanya Lattner20890832004-05-28 20:14:12 +00001727 std::map<int, std::set<const MachineInstr*> > inKernel;
Tanya Lattner420025b2004-10-10 22:44:35 +00001728
Tanya Lattner20890832004-05-28 20:14:12 +00001729 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
Tanya Lattner20890832004-05-28 20:14:12 +00001730
1731 //Ignore the branch, we will handle this separately
1732 if(I->first->isBranch())
1733 continue;
1734
1735 //Put int the map so we know what instructions in each stage are in the kernel
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001736 inKernel[I->second].insert(I->first->getInst());
Tanya Lattner20890832004-05-28 20:14:12 +00001737 }
1738
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001739 std::map<Value*, Value*> valPHIs;
1740
Tanya Lattner420025b2004-10-10 22:44:35 +00001741 //some debug stuff, will remove later
1742 DEBUG(for(std::map<Value*, std::map<int, Value*> >::iterator V = newValues.begin(), E = newValues.end(); V !=E; ++V) {
1743 std::cerr << "Old Value: " << *(V->first) << "\n";
1744 for(std::map<int, Value*>::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I)
1745 std::cerr << "Stage: " << I->first << " Value: " << *(I->second) << "\n";
1746 });
1747
1748 //some debug stuff, will remove later
1749 DEBUG(for(std::map<Value*, std::map<int, Value*> >::iterator V = kernelPHIs.begin(), E = kernelPHIs.end(); V !=E; ++V) {
1750 std::cerr << "Old Value: " << *(V->first) << "\n";
1751 for(std::map<int, Value*>::iterator I = V->second.begin(), IE = V->second.end(); I != IE; ++I)
1752 std::cerr << "Stage: " << I->first << " Value: " << *(I->second) << "\n";
1753 });
1754
Tanya Lattner20890832004-05-28 20:14:12 +00001755 //Now write the epilogues
Tanya Lattner420025b2004-10-10 22:44:35 +00001756 for(int i = schedule.getMaxStage()-1; i >= 0; --i) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001757 BasicBlock *llvmBB = new BasicBlock("EPILOGUE", (Function*) (origBB->getBasicBlock()->getParent()));
Tanya Lattner20890832004-05-28 20:14:12 +00001758 MachineBasicBlock *machineBB = new MachineBasicBlock(llvmBB);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001759
Tanya Lattner420025b2004-10-10 22:44:35 +00001760 DEBUG(std::cerr << " Epilogue #: " << i << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001761
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001762
Tanya Lattnera6457502004-10-14 06:04:28 +00001763 std::map<Value*, int> inEpilogue;
Tanya Lattner420025b2004-10-10 22:44:35 +00001764
1765 for(MachineBasicBlock::const_iterator MI = origBB->begin(), ME = origBB->end(); ME != MI; ++MI) {
1766 for(int j=schedule.getMaxStage(); j > i; --j) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001767 if(inKernel[j].count(&*MI)) {
1768 DEBUG(std::cerr << "Cloning instruction " << *MI << "\n");
1769 MachineInstr *clone = MI->clone();
1770
1771 //Update operands that need to use the result from the phi
Tanya Lattner420025b2004-10-10 22:44:35 +00001772 for(unsigned opNum=0; opNum < clone->getNumOperands(); ++opNum) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001773 //get machine operand
Tanya Lattner420025b2004-10-10 22:44:35 +00001774 const MachineOperand &mOp = clone->getOperand(opNum);
Tanya Lattner420025b2004-10-10 22:44:35 +00001775
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001776 if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse())) {
Tanya Lattner420025b2004-10-10 22:44:35 +00001777
1778 DEBUG(std::cerr << "Writing PHI for " << *(mOp.getVRegValue()) << "\n");
Tanya Lattnera6457502004-10-14 06:04:28 +00001779
1780 //If this is the last instructions for the max iterations ago, don't update operands
1781 if(inEpilogue.count(mOp.getVRegValue()))
1782 if(inEpilogue[mOp.getVRegValue()] == i)
1783 continue;
Tanya Lattner420025b2004-10-10 22:44:35 +00001784
1785 //Quickly write appropriate phis for this operand
1786 if(newValues.count(mOp.getVRegValue())) {
1787 if(newValues[mOp.getVRegValue()].count(i)) {
1788 Instruction *tmp = new TmpInstruction(newValues[mOp.getVRegValue()][i]);
Tanya Lattnera6457502004-10-14 06:04:28 +00001789
1790 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00001791 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00001792 tempMvec.addTemp((Value*) tmp);
1793
Tanya Lattner420025b2004-10-10 22:44:35 +00001794 MachineInstr *saveValue = BuildMI(machineBB, V9::PHI, 3).addReg(newValues[mOp.getVRegValue()][i]).addReg(kernelPHIs[mOp.getVRegValue()][i]).addRegDef(tmp);
1795 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
1796 valPHIs[mOp.getVRegValue()] = tmp;
1797 }
1798 }
1799
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001800 if(valPHIs.count(mOp.getVRegValue())) {
1801 //Update the operand in the cloned instruction
Tanya Lattner420025b2004-10-10 22:44:35 +00001802 clone->getOperand(opNum).setValueReg(valPHIs[mOp.getVRegValue()]);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001803 }
1804 }
Tanya Lattnera6457502004-10-14 06:04:28 +00001805 else if((mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef())) {
1806 inEpilogue[mOp.getVRegValue()] = i;
1807 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001808 }
1809 machineBB->push_back(clone);
1810 }
1811 }
Tanya Lattner420025b2004-10-10 22:44:35 +00001812 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001813
Tanya Lattner20890832004-05-28 20:14:12 +00001814 (((MachineBasicBlock*)origBB)->getParent())->getBasicBlockList().push_back(machineBB);
1815 epilogues.push_back(machineBB);
1816 llvm_epilogues.push_back(llvmBB);
Tanya Lattner420025b2004-10-10 22:44:35 +00001817
1818 DEBUG(std::cerr << "EPILOGUE #" << i << "\n");
1819 DEBUG(machineBB->print(std::cerr));
Tanya Lattner20890832004-05-28 20:14:12 +00001820 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001821}
1822
Tanya Lattner420025b2004-10-10 22:44:35 +00001823void ModuloSchedulingPass::writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MSchedGraphNode*, 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 +00001824
1825 //Keep track of operands that are read and saved from a previous iteration. The new clone
1826 //instruction will use the result of the phi instead.
1827 std::map<Value*, Value*> finalPHIValue;
1828 std::map<Value*, Value*> kernelValue;
1829
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00001830 //Branches are a special case
1831 std::vector<MachineInstr*> branches;
1832
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001833 //Create TmpInstructions for the final phis
1834 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
1835
Tanya Lattner420025b2004-10-10 22:44:35 +00001836 DEBUG(std::cerr << "Stage: " << I->second << " Inst: " << *(I->first->getInst()) << "\n";);
1837
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00001838 if(I->first->isBranch()) {
1839 //Clone instruction
1840 const MachineInstr *inst = I->first->getInst();
1841 MachineInstr *instClone = inst->clone();
1842 branches.push_back(instClone);
Tanya Lattner01114742005-01-18 04:15:41 +00001843 continue;
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00001844 }
1845
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001846 //Clone instruction
1847 const MachineInstr *inst = I->first->getInst();
1848 MachineInstr *instClone = inst->clone();
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001849
Tanya Lattner420025b2004-10-10 22:44:35 +00001850 //Insert into machine basic block
1851 machineBB->push_back(instClone);
1852
Tanya Lattnerced82222004-11-16 21:31:37 +00001853 DEBUG(std::cerr << "Cloned Inst: " << *instClone << "\n");
1854
Tanya Lattner420025b2004-10-10 22:44:35 +00001855 //Loop over Machine Operands
1856 for(unsigned i=0; i < inst->getNumOperands(); ++i) {
1857 //get machine operand
1858 const MachineOperand &mOp = inst->getOperand(i);
1859
1860 if(I->second != 0) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001861 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
Tanya Lattner420025b2004-10-10 22:44:35 +00001862
1863 //Check to see where this operand is defined if this instruction is from max stage
1864 if(I->second == schedule.getMaxStage()) {
1865 DEBUG(std::cerr << "VREG: " << *(mOp.getVRegValue()) << "\n");
1866 }
1867
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001868 //If its in the value saved, we need to create a temp instruction and use that instead
1869 if(valuesToSave.count(mOp.getVRegValue())) {
Tanya Lattnerced82222004-11-16 21:31:37 +00001870
1871 //Check if we already have a final PHI value for this
1872 if(!finalPHIValue.count(mOp.getVRegValue())) {
1873 TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
1874
1875 //Get machine code for this instruction
1876 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
1877 tempMvec.addTemp((Value*) tmp);
1878
1879 //Update the operand in the cloned instruction
1880 instClone->getOperand(i).setValueReg(tmp);
1881
1882 //save this as our final phi
1883 finalPHIValue[mOp.getVRegValue()] = tmp;
1884 newValLocation[tmp] = machineBB;
1885 }
1886 else {
1887 //Use the previous final phi value
1888 instClone->getOperand(i).setValueReg(finalPHIValue[mOp.getVRegValue()]);
1889 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001890 }
1891 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001892 }
Tanya Lattner420025b2004-10-10 22:44:35 +00001893 if(I->second != schedule.getMaxStage()) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001894 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isDef()) {
1895 if(valuesToSave.count(mOp.getVRegValue())) {
1896
1897 TmpInstruction *tmp = new TmpInstruction(mOp.getVRegValue());
1898
Tanya Lattnera6457502004-10-14 06:04:28 +00001899 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00001900 MachineCodeForInstruction & tempVec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00001901 tempVec.addTemp((Value*) tmp);
1902
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001903 //Create new machine instr and put in MBB
1904 MachineInstr *saveValue = BuildMI(machineBB, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
1905
1906 //Save for future cleanup
1907 kernelValue[mOp.getVRegValue()] = tmp;
1908 newValLocation[tmp] = machineBB;
Tanya Lattner420025b2004-10-10 22:44:35 +00001909 kernelPHIs[mOp.getVRegValue()][schedule.getMaxStage()-1] = tmp;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001910 }
1911 }
1912 }
1913 }
Tanya Lattner420025b2004-10-10 22:44:35 +00001914
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001915 }
1916
Tanya Lattnerf3fa55f2004-12-03 05:25:22 +00001917 //Add branches
1918 for(std::vector<MachineInstr*>::iterator I = branches.begin(), E = branches.end(); I != E; ++I) {
1919 machineBB->push_back(*I);
1920 BuildMI(machineBB, V9::NOP, 0);
1921 }
1922
1923
Tanya Lattner420025b2004-10-10 22:44:35 +00001924 DEBUG(std::cerr << "KERNEL before PHIs\n");
1925 DEBUG(machineBB->print(std::cerr));
1926
1927
1928 //Loop over each value we need to generate phis for
1929 for(std::map<Value*, std::map<int, Value*> >::iterator V = newValues.begin(),
1930 E = newValues.end(); V != E; ++V) {
1931
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001932
1933 DEBUG(std::cerr << "Writing phi for" << *(V->first));
Tanya Lattner420025b2004-10-10 22:44:35 +00001934 DEBUG(std::cerr << "\nMap of Value* for this phi\n");
1935 DEBUG(for(std::map<int, Value*>::iterator I = V->second.begin(),
1936 IE = V->second.end(); I != IE; ++I) {
1937 std::cerr << "Stage: " << I->first;
1938 std::cerr << " Value: " << *(I->second) << "\n";
1939 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001940
Tanya Lattner420025b2004-10-10 22:44:35 +00001941 //If we only have one current iteration live, its safe to set lastPhi = to kernel value
1942 if(V->second.size() == 1) {
1943 assert(kernelValue[V->first] != 0 && "Kernel value* must exist to create phi");
1944 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(),V9::PHI, 3).addReg(V->second.begin()->second).addReg(kernelValue[V->first]).addRegDef(finalPHIValue[V->first]);
1945 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
1946 kernelPHIs[V->first][schedule.getMaxStage()-1] = kernelValue[V->first];
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00001947 }
Tanya Lattner420025b2004-10-10 22:44:35 +00001948 else {
1949
1950 //Keep track of last phi created.
1951 Instruction *lastPhi = 0;
1952
1953 unsigned count = 1;
1954 //Loop over the the map backwards to generate phis
1955 for(std::map<int, Value*>::reverse_iterator I = V->second.rbegin(), IE = V->second.rend();
1956 I != IE; ++I) {
1957
1958 if(count < (V->second).size()) {
1959 if(lastPhi == 0) {
1960 lastPhi = new TmpInstruction(I->second);
Tanya Lattnera6457502004-10-14 06:04:28 +00001961
1962 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00001963 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00001964 tempMvec.addTemp((Value*) lastPhi);
1965
Tanya Lattner420025b2004-10-10 22:44:35 +00001966 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(kernelValue[V->first]).addReg(I->second).addRegDef(lastPhi);
1967 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
1968 newValLocation[lastPhi] = machineBB;
1969 }
1970 else {
1971 Instruction *tmp = new TmpInstruction(I->second);
Tanya Lattnera6457502004-10-14 06:04:28 +00001972
1973 //Get machine code for this instruction
Tanya Lattner80f08552004-11-02 21:04:56 +00001974 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
Tanya Lattnera6457502004-10-14 06:04:28 +00001975 tempMvec.addTemp((Value*) tmp);
1976
1977
Tanya Lattner420025b2004-10-10 22:44:35 +00001978 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(tmp);
1979 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
1980 lastPhi = tmp;
1981 kernelPHIs[V->first][I->first] = lastPhi;
1982 newValLocation[lastPhi] = machineBB;
1983 }
1984 }
1985 //Final phi value
1986 else {
1987 //The resulting value must be the Value* we created earlier
1988 assert(lastPhi != 0 && "Last phi is NULL!\n");
1989 MachineInstr *saveValue = BuildMI(*machineBB, machineBB->begin(), V9::PHI, 3).addReg(lastPhi).addReg(I->second).addRegDef(finalPHIValue[V->first]);
1990 DEBUG(std::cerr << "Resulting PHI: " << *saveValue << "\n");
1991 kernelPHIs[V->first][I->first] = finalPHIValue[V->first];
1992 }
1993
1994 ++count;
1995 }
1996
1997 }
1998 }
1999
2000 DEBUG(std::cerr << "KERNEL after PHIs\n");
2001 DEBUG(machineBB->print(std::cerr));
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002002}
2003
Tanya Lattner420025b2004-10-10 22:44:35 +00002004
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002005void ModuloSchedulingPass::removePHIs(const MachineBasicBlock *origBB, std::vector<MachineBasicBlock *> &prologues, std::vector<MachineBasicBlock *> &epilogues, MachineBasicBlock *kernelBB, std::map<Value*, MachineBasicBlock*> &newValLocation) {
2006
2007 //Worklist to delete things
2008 std::vector<std::pair<MachineBasicBlock*, MachineBasicBlock::iterator> > worklist;
Tanya Lattnera6457502004-10-14 06:04:28 +00002009
2010 //Worklist of TmpInstructions that need to be added to a MCFI
2011 std::vector<Instruction*> addToMCFI;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002012
Tanya Lattnera6457502004-10-14 06:04:28 +00002013 //Worklist to add OR instructions to end of kernel so not to invalidate the iterator
2014 //std::vector<std::pair<Instruction*, Value*> > newORs;
2015
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002016 const TargetInstrInfo *TMI = target.getInstrInfo();
2017
2018 //Start with the kernel and for each phi insert a copy for the phi def and for each arg
2019 for(MachineBasicBlock::iterator I = kernelBB->begin(), E = kernelBB->end(); I != E; ++I) {
Tanya Lattnera6457502004-10-14 06:04:28 +00002020
Tanya Lattner80f08552004-11-02 21:04:56 +00002021 DEBUG(std::cerr << "Looking at Instr: " << *I << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002022 //Get op code and check if its a phi
Tanya Lattnera6457502004-10-14 06:04:28 +00002023 if(I->getOpcode() == V9::PHI) {
2024
2025 DEBUG(std::cerr << "Replacing PHI: " << *I << "\n");
2026 Instruction *tmp = 0;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002027
Tanya Lattnera6457502004-10-14 06:04:28 +00002028 for(unsigned i = 0; i < I->getNumOperands(); ++i) {
2029 //Get Operand
2030 const MachineOperand &mOp = I->getOperand(i);
2031 assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
2032
2033 if(!tmp) {
2034 tmp = new TmpInstruction(mOp.getVRegValue());
2035 addToMCFI.push_back(tmp);
2036 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002037
Tanya Lattnera6457502004-10-14 06:04:28 +00002038 //Now for all our arguments we read, OR to the new TmpInstruction that we created
2039 if(mOp.isUse()) {
2040 DEBUG(std::cerr << "Use: " << mOp << "\n");
2041 //Place a copy at the end of its BB but before the branches
2042 assert(newValLocation.count(mOp.getVRegValue()) && "We must know where this value is located\n");
2043 //Reverse iterate to find the branches, we can safely assume no instructions have been
2044 //put in the nop positions
2045 for(MachineBasicBlock::iterator inst = --(newValLocation[mOp.getVRegValue()])->end(), endBB = (newValLocation[mOp.getVRegValue()])->begin(); inst != endBB; --inst) {
2046 MachineOpCode opc = inst->getOpcode();
2047 if(TMI->isBranch(opc) || TMI->isNop(opc))
2048 continue;
2049 else {
2050 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
2051 break;
2052 }
2053
2054 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002055
Tanya Lattnera6457502004-10-14 06:04:28 +00002056 }
2057 else {
2058 //Remove the phi and replace it with an OR
2059 DEBUG(std::cerr << "Def: " << mOp << "\n");
2060 //newORs.push_back(std::make_pair(tmp, mOp.getVRegValue()));
2061 BuildMI(*kernelBB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
2062 worklist.push_back(std::make_pair(kernelBB, I));
2063 }
2064
2065 }
2066
2067 }
2068
Tanya Lattnera6457502004-10-14 06:04:28 +00002069
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002070 }
2071
Tanya Lattner80f08552004-11-02 21:04:56 +00002072 //Add TmpInstructions to some MCFI
2073 if(addToMCFI.size() > 0) {
2074 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
2075 for(unsigned x = 0; x < addToMCFI.size(); ++x) {
2076 tempMvec.addTemp(addToMCFI[x]);
2077 }
2078 addToMCFI.clear();
2079 }
2080
Tanya Lattnera6457502004-10-14 06:04:28 +00002081
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002082 //Remove phis from epilogue
2083 for(std::vector<MachineBasicBlock*>::iterator MB = epilogues.begin(), ME = epilogues.end(); MB != ME; ++MB) {
2084 for(MachineBasicBlock::iterator I = (*MB)->begin(), E = (*MB)->end(); I != E; ++I) {
Tanya Lattner80f08552004-11-02 21:04:56 +00002085
2086 DEBUG(std::cerr << "Looking at Instr: " << *I << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002087 //Get op code and check if its a phi
Brian Gaeke418379e2004-08-18 20:04:24 +00002088 if(I->getOpcode() == V9::PHI) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002089 Instruction *tmp = 0;
Tanya Lattnera6457502004-10-14 06:04:28 +00002090
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002091 for(unsigned i = 0; i < I->getNumOperands(); ++i) {
2092 //Get Operand
2093 const MachineOperand &mOp = I->getOperand(i);
2094 assert(mOp.getType() == MachineOperand::MO_VirtualRegister && "Should be a Value*\n");
2095
2096 if(!tmp) {
2097 tmp = new TmpInstruction(mOp.getVRegValue());
Tanya Lattnera6457502004-10-14 06:04:28 +00002098 addToMCFI.push_back(tmp);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002099 }
2100
2101 //Now for all our arguments we read, OR to the new TmpInstruction that we created
2102 if(mOp.isUse()) {
2103 DEBUG(std::cerr << "Use: " << mOp << "\n");
2104 //Place a copy at the end of its BB but before the branches
2105 assert(newValLocation.count(mOp.getVRegValue()) && "We must know where this value is located\n");
2106 //Reverse iterate to find the branches, we can safely assume no instructions have been
2107 //put in the nop positions
2108 for(MachineBasicBlock::iterator inst = --(newValLocation[mOp.getVRegValue()])->end(), endBB = (newValLocation[mOp.getVRegValue()])->begin(); inst != endBB; --inst) {
2109 MachineOpCode opc = inst->getOpcode();
2110 if(TMI->isBranch(opc) || TMI->isNop(opc))
2111 continue;
2112 else {
2113 BuildMI(*(newValLocation[mOp.getVRegValue()]), ++inst, V9::ORr, 3).addReg(mOp.getVRegValue()).addImm(0).addRegDef(tmp);
2114 break;
2115 }
2116
2117 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002118
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002119 }
2120 else {
2121 //Remove the phi and replace it with an OR
2122 DEBUG(std::cerr << "Def: " << mOp << "\n");
2123 BuildMI(**MB, I, V9::ORr, 3).addReg(tmp).addImm(0).addRegDef(mOp.getVRegValue());
2124 worklist.push_back(std::make_pair(*MB,I));
2125 }
2126
2127 }
2128 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002129
Tanya Lattner80f08552004-11-02 21:04:56 +00002130
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002131 }
2132 }
2133
Tanya Lattner80f08552004-11-02 21:04:56 +00002134
2135 if(addToMCFI.size() > 0) {
2136 MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(defaultInst);
2137 for(unsigned x = 0; x < addToMCFI.size(); ++x) {
2138 tempMvec.addTemp(addToMCFI[x]);
2139 }
2140 addToMCFI.clear();
2141 }
2142
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002143 //Delete the phis
2144 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 +00002145
2146 DEBUG(std::cerr << "Deleting PHI " << *I->second << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002147 I->first->erase(I->second);
2148
2149 }
2150
Tanya Lattnera6457502004-10-14 06:04:28 +00002151
2152 assert((addToMCFI.size() == 0) && "We should have added all TmpInstructions to some MachineCodeForInstruction");
Tanya Lattner20890832004-05-28 20:14:12 +00002153}
2154
2155
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002156void ModuloSchedulingPass::reconstructLoop(MachineBasicBlock *BB) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002157
Tanya Lattnerdb40cf12005-02-10 17:02:58 +00002158 TIME_REGION(X, "reconstructLoop");
2159
2160
Tanya Lattner420025b2004-10-10 22:44:35 +00002161 DEBUG(std::cerr << "Reconstructing Loop\n");
2162
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002163 //First find the value *'s that we need to "save"
2164 std::map<const Value*, std::pair<const MSchedGraphNode*, int> > valuesToSave;
Tanya Lattner4cffb582004-05-26 06:27:18 +00002165
Tanya Lattner420025b2004-10-10 22:44:35 +00002166 //Keep track of instructions we have already seen and their stage because
2167 //we don't want to "save" values if they are used in the kernel immediately
2168 std::map<const MachineInstr*, int> lastInstrs;
2169
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002170 //Loop over kernel and only look at instructions from a stage > 0
2171 //Look at its operands and save values *'s that are read
Tanya Lattner4cffb582004-05-26 06:27:18 +00002172 for(MSSchedule::kernel_iterator I = schedule.kernel_begin(), E = schedule.kernel_end(); I != E; ++I) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002173
Tanya Lattner420025b2004-10-10 22:44:35 +00002174 if(I->second !=0) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002175 //For this instruction, get the Value*'s that it reads and put them into the set.
2176 //Assert if there is an operand of another type that we need to save
2177 const MachineInstr *inst = I->first->getInst();
Tanya Lattner420025b2004-10-10 22:44:35 +00002178 lastInstrs[inst] = I->second;
2179
Tanya Lattner4cffb582004-05-26 06:27:18 +00002180 for(unsigned i=0; i < inst->getNumOperands(); ++i) {
2181 //get machine operand
2182 const MachineOperand &mOp = inst->getOperand(i);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002183
Tanya Lattner4cffb582004-05-26 06:27:18 +00002184 if(mOp.getType() == MachineOperand::MO_VirtualRegister && mOp.isUse()) {
2185 //find the value in the map
Tanya Lattner420025b2004-10-10 22:44:35 +00002186 if (const Value* srcI = mOp.getVRegValue()) {
2187
Tanya Lattnerced82222004-11-16 21:31:37 +00002188 if(isa<Constant>(srcI) || isa<Argument>(srcI) || isa<PHINode>(srcI))
Tanya Lattner80f08552004-11-02 21:04:56 +00002189 continue;
2190
Tanya Lattner420025b2004-10-10 22:44:35 +00002191 //Before we declare this Value* one that we should save
2192 //make sure its def is not of the same stage as this instruction
2193 //because it will be consumed before its used
2194 Instruction *defInst = (Instruction*) srcI;
2195
2196 //Should we save this value?
2197 bool save = true;
2198
Tanya Lattnerced82222004-11-16 21:31:37 +00002199 //Continue if not in the def map, loop invariant code does not need to be saved
2200 if(!defMap.count(srcI))
2201 continue;
2202
Tanya Lattner80f08552004-11-02 21:04:56 +00002203 MachineInstr *defInstr = defMap[srcI];
2204
Tanya Lattnerced82222004-11-16 21:31:37 +00002205
Tanya Lattner80f08552004-11-02 21:04:56 +00002206 if(lastInstrs.count(defInstr)) {
Tanya Lattnerced82222004-11-16 21:31:37 +00002207 if(lastInstrs[defInstr] == I->second) {
Tanya Lattner80f08552004-11-02 21:04:56 +00002208 save = false;
Tanya Lattnerced82222004-11-16 21:31:37 +00002209
2210 }
Tanya Lattner420025b2004-10-10 22:44:35 +00002211 }
Tanya Lattner80f08552004-11-02 21:04:56 +00002212
Tanya Lattner420025b2004-10-10 22:44:35 +00002213 if(save)
2214 valuesToSave[srcI] = std::make_pair(I->first, i);
2215 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00002216 }
2217
2218 if(mOp.getType() != MachineOperand::MO_VirtualRegister && mOp.isUse()) {
2219 assert("Our assumption is wrong. We have another type of register that needs to be saved\n");
2220 }
2221 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00002222 }
2223 }
2224
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002225 //The new loop will consist of one or more prologues, the kernel, and one or more epilogues.
2226
2227 //Map to keep track of old to new values
Tanya Lattner420025b2004-10-10 22:44:35 +00002228 std::map<Value*, std::map<int, Value*> > newValues;
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002229
Tanya Lattner420025b2004-10-10 22:44:35 +00002230 //Map to keep track of old to new values in kernel
2231 std::map<Value*, std::map<int, Value*> > kernelPHIs;
2232
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002233 //Another map to keep track of what machine basic blocks these new value*s are in since
2234 //they have no llvm instruction equivalent
2235 std::map<Value*, MachineBasicBlock*> newValLocation;
2236
2237 std::vector<MachineBasicBlock*> prologues;
2238 std::vector<BasicBlock*> llvm_prologues;
2239
2240
2241 //Write prologue
2242 writePrologues(prologues, BB, llvm_prologues, valuesToSave, newValues, newValLocation);
Tanya Lattner420025b2004-10-10 22:44:35 +00002243
2244 //Print out epilogues and prologue
2245 DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = prologues.begin(), E = prologues.end();
2246 I != E; ++I) {
2247 std::cerr << "PROLOGUE\n";
2248 (*I)->print(std::cerr);
2249 });
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002250
2251 BasicBlock *llvmKernelBB = new BasicBlock("Kernel", (Function*) (BB->getBasicBlock()->getParent()));
2252 MachineBasicBlock *machineKernelBB = new MachineBasicBlock(llvmKernelBB);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002253 (((MachineBasicBlock*)BB)->getParent())->getBasicBlockList().push_back(machineKernelBB);
Tanya Lattner420025b2004-10-10 22:44:35 +00002254 writeKernel(llvmKernelBB, machineKernelBB, valuesToSave, newValues, newValLocation, kernelPHIs);
2255
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002256
2257 std::vector<MachineBasicBlock*> epilogues;
2258 std::vector<BasicBlock*> llvm_epilogues;
2259
2260 //Write epilogues
Tanya Lattner420025b2004-10-10 22:44:35 +00002261 writeEpilogues(epilogues, BB, llvm_epilogues, valuesToSave, newValues, newValLocation, kernelPHIs);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002262
2263
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002264 //Fix our branches
2265 fixBranches(prologues, llvm_prologues, machineKernelBB, llvmKernelBB, epilogues, llvm_epilogues, BB);
2266
2267 //Remove phis
2268 removePHIs(BB, prologues, epilogues, machineKernelBB, newValLocation);
2269
2270 //Print out epilogues and prologue
2271 DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = prologues.begin(), E = prologues.end();
2272 I != E; ++I) {
2273 std::cerr << "PROLOGUE\n";
2274 (*I)->print(std::cerr);
2275 });
2276
2277 DEBUG(std::cerr << "KERNEL\n");
2278 DEBUG(machineKernelBB->print(std::cerr));
2279
2280 DEBUG(for(std::vector<MachineBasicBlock*>::iterator I = epilogues.begin(), E = epilogues.end();
2281 I != E; ++I) {
2282 std::cerr << "EPILOGUE\n";
2283 (*I)->print(std::cerr);
2284 });
2285
2286
2287 DEBUG(std::cerr << "New Machine Function" << "\n");
2288 DEBUG(std::cerr << BB->getParent() << "\n");
2289
2290
2291}
2292
2293void 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) {
2294
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002295 const TargetInstrInfo *TMI = target.getInstrInfo();
2296
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002297 //Fix prologue branches
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002298 for(unsigned I = 0; I < prologues.size(); ++I) {
2299
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002300 //Find terminator since getFirstTerminator does not work!
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002301 for(MachineBasicBlock::reverse_iterator mInst = prologues[I]->rbegin(), mInstEnd = prologues[I]->rend(); mInst != mInstEnd; ++mInst) {
2302 MachineOpCode OC = mInst->getOpcode();
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002303 //If its a branch update its branchto
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002304 if(TMI->isBranch(OC)) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002305 for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) {
2306 MachineOperand &mOp = mInst->getOperand(opNum);
2307 if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2308 //Check if we are branching to the kernel, if not branch to epilogue
2309 if(mOp.getVRegValue() == BB->getBasicBlock()) {
2310 if(I == prologues.size()-1)
2311 mOp.setValueReg(llvmKernelBB);
2312 else
2313 mOp.setValueReg(llvm_prologues[I+1]);
2314 }
2315 else {
2316 mOp.setValueReg(llvm_epilogues[(llvm_epilogues.size()-1-I)]);
2317 }
2318 }
2319 }
2320
2321 DEBUG(std::cerr << "New Prologue Branch: " << *mInst << "\n");
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002322 }
2323 }
2324
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002325
2326 //Update llvm basic block with our new branch instr
2327 DEBUG(std::cerr << BB->getBasicBlock()->getTerminator() << "\n");
2328 const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002329
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002330 if(I == prologues.size()-1) {
2331 TerminatorInst *newBranch = new BranchInst(llvmKernelBB,
2332 llvm_epilogues[(llvm_epilogues.size()-1-I)],
Tanya Lattnera6457502004-10-14 06:04:28 +00002333 branchVal->getCondition(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002334 llvm_prologues[I]);
2335 }
2336 else
2337 TerminatorInst *newBranch = new BranchInst(llvm_prologues[I+1],
2338 llvm_epilogues[(llvm_epilogues.size()-1-I)],
Tanya Lattnera6457502004-10-14 06:04:28 +00002339 branchVal->getCondition(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002340 llvm_prologues[I]);
2341
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002342 }
2343
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002344 Value *origBranchExit = 0;
Tanya Lattnera6457502004-10-14 06:04:28 +00002345
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002346 //Fix up kernel machine branches
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002347 for(MachineBasicBlock::reverse_iterator mInst = machineKernelBB->rbegin(), mInstEnd = machineKernelBB->rend(); mInst != mInstEnd; ++mInst) {
2348 MachineOpCode OC = mInst->getOpcode();
2349 if(TMI->isBranch(OC)) {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002350 for(unsigned opNum = 0; opNum < mInst->getNumOperands(); ++opNum) {
2351 MachineOperand &mOp = mInst->getOperand(opNum);
2352
2353 if(mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2354 if(mOp.getVRegValue() == BB->getBasicBlock())
2355 mOp.setValueReg(llvmKernelBB);
2356 else
2357 if(llvm_epilogues.size() > 0) {
2358 assert(origBranchExit == 0 && "There should only be one branch out of the loop");
2359
2360 origBranchExit = mOp.getVRegValue();
2361 mOp.setValueReg(llvm_epilogues[0]);
2362 }
2363 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002364 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002365 }
2366 }
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002367
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002368 //Update kernelLLVM branches
2369 const BranchInst *branchVal = dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
Tanya Lattnera6457502004-10-14 06:04:28 +00002370
Tanya Lattner260652a2004-10-30 00:39:07 +00002371 assert(llvm_epilogues.size() != 0 && "We must have epilogues!");
2372
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002373 TerminatorInst *newBranch = new BranchInst(llvmKernelBB,
2374 llvm_epilogues[0],
Tanya Lattnera6457502004-10-14 06:04:28 +00002375 branchVal->getCondition(),
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002376 llvmKernelBB);
2377
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002378
2379 //Lastly add unconditional branches for the epilogues
2380 for(unsigned I = 0; I < epilogues.size(); ++I) {
Tanya Lattner4cffb582004-05-26 06:27:18 +00002381
Tanya Lattnera6457502004-10-14 06:04:28 +00002382 //Now since we don't have fall throughs, add a unconditional branch to the next prologue
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002383 if(I != epilogues.size()-1) {
Tanya Lattner420025b2004-10-10 22:44:35 +00002384 BuildMI(epilogues[I], V9::BA, 1).addPCDisp(llvm_epilogues[I+1]);
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002385 //Add unconditional branch to end of epilogue
2386 TerminatorInst *newBranch = new BranchInst(llvm_epilogues[I+1],
2387 llvm_epilogues[I]);
2388
Tanya Lattner4cffb582004-05-26 06:27:18 +00002389 }
Tanya Lattnera6457502004-10-14 06:04:28 +00002390 else {
Tanya Lattner58fe2f02004-11-29 04:39:47 +00002391 BuildMI(epilogues[I], V9::BA, 1).addPCDisp(origBranchExit);
Tanya Lattnera6457502004-10-14 06:04:28 +00002392
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002393
Tanya Lattnera6457502004-10-14 06:04:28 +00002394 //Update last epilogue exit branch
2395 BranchInst *branchVal = (BranchInst*) dyn_cast<BranchInst>(BB->getBasicBlock()->getTerminator());
2396 //Find where we are supposed to branch to
2397 BasicBlock *nextBlock = 0;
2398 for(unsigned j=0; j <branchVal->getNumSuccessors(); ++j) {
2399 if(branchVal->getSuccessor(j) != BB->getBasicBlock())
2400 nextBlock = branchVal->getSuccessor(j);
2401 }
2402
2403 assert((nextBlock != 0) && "Next block should not be null!");
2404 TerminatorInst *newBranch = new BranchInst(nextBlock, llvm_epilogues[I]);
2405 }
2406 //Add one more nop!
2407 BuildMI(epilogues[I], V9::NOP, 0);
2408
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002409 }
Tanya Lattner4cffb582004-05-26 06:27:18 +00002410
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002411 //FIX UP Machine BB entry!!
2412 //We are looking at the predecesor of our loop basic block and we want to change its ba instruction
2413
Tanya Lattner4cffb582004-05-26 06:27:18 +00002414
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002415 //Find all llvm basic blocks that branch to the loop entry and change to our first prologue.
2416 const BasicBlock *llvmBB = BB->getBasicBlock();
2417
Tanya Lattner260652a2004-10-30 00:39:07 +00002418 std::vector<const BasicBlock*>Preds (pred_begin(llvmBB), pred_end(llvmBB));
2419
2420 //for(pred_const_iterator P = pred_begin(llvmBB), PE = pred_end(llvmBB); P != PE; ++PE) {
2421 for(std::vector<const BasicBlock*>::iterator P = Preds.begin(), PE = Preds.end(); P != PE; ++P) {
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002422 if(*P == llvmBB)
2423 continue;
2424 else {
2425 DEBUG(std::cerr << "Found our entry BB\n");
2426 //Get the Terminator instruction for this basic block and print it out
2427 DEBUG(std::cerr << *((*P)->getTerminator()) << "\n");
2428 //Update the terminator
2429 TerminatorInst *term = ((BasicBlock*)*P)->getTerminator();
2430 for(unsigned i=0; i < term->getNumSuccessors(); ++i) {
2431 if(term->getSuccessor(i) == llvmBB) {
2432 DEBUG(std::cerr << "Replacing successor bb\n");
2433 if(llvm_prologues.size() > 0) {
2434 term->setSuccessor(i, llvm_prologues[0]);
2435 //Also update its corresponding machine instruction
2436 MachineCodeForInstruction & tempMvec =
2437 MachineCodeForInstruction::get(term);
2438 for (unsigned j = 0; j < tempMvec.size(); j++) {
2439 MachineInstr *temp = tempMvec[j];
2440 MachineOpCode opc = temp->getOpcode();
2441 if(TMI->isBranch(opc)) {
2442 DEBUG(std::cerr << *temp << "\n");
2443 //Update branch
2444 for(unsigned opNum = 0; opNum < temp->getNumOperands(); ++opNum) {
2445 MachineOperand &mOp = temp->getOperand(opNum);
2446 if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2447 mOp.setValueReg(llvm_prologues[0]);
2448 }
2449 }
2450 }
2451 }
2452 }
2453 else {
2454 term->setSuccessor(i, llvmKernelBB);
2455 //Also update its corresponding machine instruction
2456 MachineCodeForInstruction & tempMvec =
2457 MachineCodeForInstruction::get(term);
2458 for (unsigned j = 0; j < tempMvec.size(); j++) {
2459 MachineInstr *temp = tempMvec[j];
2460 MachineOpCode opc = temp->getOpcode();
2461 if(TMI->isBranch(opc)) {
2462 DEBUG(std::cerr << *temp << "\n");
2463 //Update branch
2464 for(unsigned opNum = 0; opNum < temp->getNumOperands(); ++opNum) {
2465 MachineOperand &mOp = temp->getOperand(opNum);
2466 if (mOp.getType() == MachineOperand::MO_PCRelativeDisp) {
2467 mOp.setValueReg(llvmKernelBB);
2468 }
2469 }
2470 }
2471 }
2472 }
2473 }
2474 }
2475 break;
2476 }
2477 }
2478
Tanya Lattner0a88d2d2004-07-30 23:36:10 +00002479
Tanya Lattner420025b2004-10-10 22:44:35 +00002480 //BB->getParent()->getBasicBlockList().erase(BB);
Tanya Lattner4cffb582004-05-26 06:27:18 +00002481
2482}
2483