MSchedGraph.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  1. //===-- MSchedGraph.cpp - Scheduling Graph ----------------------*- C++ -*-===//
  2. //
  3. // 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.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // A graph class for dependencies. This graph only contains true, anti, and
  11. // output data dependencies for a given MachineBasicBlock. Dependencies
  12. // across iterations are also computed. Unless data dependence analysis
  13. // is provided, a conservative approach of adding dependencies between all
  14. // loads and stores is taken.
  15. //===----------------------------------------------------------------------===//
  16. #define DEBUG_TYPE "ModuloSched"
  17. #include "MSchedGraph.h"
  18. #include "../SparcV9RegisterInfo.h"
  19. #include "../MachineCodeForInstruction.h"
  20. #include "llvm/BasicBlock.h"
  21. #include "llvm/Constants.h"
  22. #include "llvm/Instructions.h"
  23. #include "llvm/Type.h"
  24. #include "llvm/CodeGen/MachineBasicBlock.h"
  25. #include "llvm/Target/TargetInstrInfo.h"
  26. #include "llvm/Support/Debug.h"
  27. #include <cstdlib>
  28. #include <algorithm>
  29. #include <set>
  30. using namespace llvm;
  31. //MSchedGraphNode constructor
  32. MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst,
  33. MSchedGraph *graph, unsigned idx,
  34. unsigned late, bool isBranch)
  35. : Inst(inst), Parent(graph), index(idx), latency(late),
  36. isBranchInstr(isBranch) {
  37. //Add to the graph
  38. graph->addNode(inst, this);
  39. }
  40. //MSchedGraphNode copy constructor
  41. MSchedGraphNode::MSchedGraphNode(const MSchedGraphNode &N)
  42. : Predecessors(N.Predecessors), Successors(N.Successors) {
  43. Inst = N.Inst;
  44. Parent = N.Parent;
  45. index = N.index;
  46. latency = N.latency;
  47. isBranchInstr = N.isBranchInstr;
  48. }
  49. //Print the node (instruction and latency)
  50. void MSchedGraphNode::print(std::ostream &os) const {
  51. os << "MSchedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n";
  52. }
  53. //Get the edge from a predecessor to this node
  54. MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) {
  55. //Loop over all the successors of our predecessor
  56. //return the edge the corresponds to this in edge
  57. for (MSchedGraphNode::succ_iterator I = pred->succ_begin(),
  58. E = pred->succ_end(); I != E; ++I) {
  59. if (*I == this)
  60. return I.getEdge();
  61. }
  62. assert(0 && "Should have found edge between this node and its predecessor!");
  63. abort();
  64. }
  65. //Get the iteration difference for the edge from this node to its successor
  66. unsigned MSchedGraphNode::getIteDiff(MSchedGraphNode *succ) {
  67. for(std::vector<MSchedGraphEdge>::iterator I = Successors.begin(),
  68. E = Successors.end();
  69. I != E; ++I) {
  70. if(I->getDest() == succ)
  71. return I->getIteDiff();
  72. }
  73. return 0;
  74. }
  75. //Get the index into the vector of edges for the edge from pred to this node
  76. unsigned MSchedGraphNode::getInEdgeNum(MSchedGraphNode *pred) {
  77. //Loop over all the successors of our predecessor
  78. //return the edge the corresponds to this in edge
  79. int count = 0;
  80. for(MSchedGraphNode::succ_iterator I = pred->succ_begin(),
  81. E = pred->succ_end();
  82. I != E; ++I) {
  83. if(*I == this)
  84. return count;
  85. count++;
  86. }
  87. assert(0 && "Should have found edge between this node and its predecessor!");
  88. abort();
  89. }
  90. //Determine if succ is a successor of this node
  91. bool MSchedGraphNode::isSuccessor(MSchedGraphNode *succ) {
  92. for(succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
  93. if(*I == succ)
  94. return true;
  95. return false;
  96. }
  97. //Dtermine if pred is a predecessor of this node
  98. bool MSchedGraphNode::isPredecessor(MSchedGraphNode *pred) {
  99. if(std::find( Predecessors.begin(), Predecessors.end(),
  100. pred) != Predecessors.end())
  101. return true;
  102. else
  103. return false;
  104. }
  105. //Add a node to the graph
  106. void MSchedGraph::addNode(const MachineInstr *MI,
  107. MSchedGraphNode *node) {
  108. //Make sure node does not already exist
  109. assert(GraphMap.find(MI) == GraphMap.end()
  110. && "New MSchedGraphNode already exists for this instruction");
  111. GraphMap[MI] = node;
  112. }
  113. //Delete a node to the graph
  114. void MSchedGraph::deleteNode(MSchedGraphNode *node) {
  115. //Delete the edge to this node from all predecessors
  116. while(node->pred_size() > 0) {
  117. //DEBUG(std::cerr << "Delete edge from: " << **P << " to " << *node << "\n");
  118. MSchedGraphNode *pred = *(node->pred_begin());
  119. pred->deleteSuccessor(node);
  120. }
  121. //Remove this node from the graph
  122. GraphMap.erase(node->getInst());
  123. }
  124. //Create a graph for a machine block. The ignoreInstrs map is so that
  125. //we ignore instructions associated to the index variable since this
  126. //is a special case in Modulo Scheduling. We only want to deal with
  127. //the body of the loop.
  128. MSchedGraph::MSchedGraph(const MachineBasicBlock *bb,
  129. const TargetMachine &targ,
  130. std::map<const MachineInstr*, unsigned> &ignoreInstrs,
  131. DependenceAnalyzer &DA,
  132. std::map<MachineInstr*, Instruction*> &machineTollvm)
  133. : Target(targ) {
  134. //Make sure BB is not null,
  135. assert(bb != NULL && "Basic Block is null");
  136. BBs.push_back(bb);
  137. //Create nodes and edges for this BB
  138. buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
  139. //Experimental!
  140. //addBranchEdges();
  141. }
  142. //Create a graph for a machine block. The ignoreInstrs map is so that
  143. //we ignore instructions associated to the index variable since this
  144. //is a special case in Modulo Scheduling. We only want to deal with
  145. //the body of the loop.
  146. MSchedGraph::MSchedGraph(std::vector<const MachineBasicBlock*> &bbs,
  147. const TargetMachine &targ,
  148. std::map<const MachineInstr*, unsigned> &ignoreInstrs,
  149. DependenceAnalyzer &DA,
  150. std::map<MachineInstr*, Instruction*> &machineTollvm)
  151. : BBs(bbs), Target(targ) {
  152. //Make sure there is at least one BB and it is not null,
  153. assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null");
  154. //Create nodes and edges for this BB
  155. buildNodesAndEdges(ignoreInstrs, DA, machineTollvm);
  156. //Experimental!
  157. //addBranchEdges();
  158. }
  159. //Copies the graph and keeps a map from old to new nodes
  160. MSchedGraph::MSchedGraph(const MSchedGraph &G,
  161. std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes)
  162. : Target(G.Target) {
  163. BBs = G.BBs;
  164. std::map<MSchedGraphNode*, MSchedGraphNode*> oldToNew;
  165. //Copy all nodes
  166. for(MSchedGraph::const_iterator N = G.GraphMap.begin(),
  167. NE = G.GraphMap.end(); N != NE; ++N) {
  168. MSchedGraphNode *newNode = new MSchedGraphNode(*(N->second));
  169. oldToNew[&*(N->second)] = newNode;
  170. newNodes[newNode] = &*(N->second);
  171. GraphMap[&*(N->first)] = newNode;
  172. }
  173. //Loop over nodes and update edges to point to new nodes
  174. for(MSchedGraph::iterator N = GraphMap.begin(), NE = GraphMap.end();
  175. N != NE; ++N) {
  176. //Get the node we are dealing with
  177. MSchedGraphNode *node = &*(N->second);
  178. node->setParent(this);
  179. //Loop over nodes successors and predecessors and update to the new nodes
  180. for(unsigned i = 0; i < node->pred_size(); ++i) {
  181. node->setPredecessor(i, oldToNew[node->getPredecessor(i)]);
  182. }
  183. for(unsigned i = 0; i < node->succ_size(); ++i) {
  184. MSchedGraphEdge *edge = node->getSuccessor(i);
  185. MSchedGraphNode *oldDest = edge->getDest();
  186. edge->setDest(oldToNew[oldDest]);
  187. }
  188. }
  189. }
  190. //Deconstructor, deletes all nodes in the graph
  191. MSchedGraph::~MSchedGraph () {
  192. for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
  193. I != E; ++I)
  194. delete I->second;
  195. }
  196. //Print out graph
  197. void MSchedGraph::print(std::ostream &os) const {
  198. for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
  199. N != NE; ++N) {
  200. //Get the node we are dealing with
  201. MSchedGraphNode *node = &*(N->second);
  202. os << "Node Start\n";
  203. node->print(os);
  204. os << "Successors:\n";
  205. //print successors
  206. for(unsigned i = 0; i < node->succ_size(); ++i) {
  207. MSchedGraphEdge *edge = node->getSuccessor(i);
  208. MSchedGraphNode *oldDest = edge->getDest();
  209. oldDest->print(os);
  210. }
  211. os << "Node End\n";
  212. }
  213. }
  214. //Calculate total delay
  215. int MSchedGraph::totalDelay() {
  216. int sum = 0;
  217. for(MSchedGraph::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
  218. N != NE; ++N) {
  219. //Get the node we are dealing with
  220. MSchedGraphNode *node = &*(N->second);
  221. sum += node->getLatency();
  222. }
  223. return sum;
  224. }
  225. //Experimental code to add edges from the branch to all nodes dependent upon it.
  226. void hasPath(MSchedGraphNode *node, std::set<MSchedGraphNode*> &visited,
  227. std::set<MSchedGraphNode*> &branches, MSchedGraphNode *startNode,
  228. std::set<std::pair<MSchedGraphNode*,MSchedGraphNode*> > &newEdges ) {
  229. visited.insert(node);
  230. DEBUG(std::cerr << "Visiting: " << *node << "\n");
  231. //Loop over successors
  232. for(unsigned i = 0; i < node->succ_size(); ++i) {
  233. MSchedGraphEdge *edge = node->getSuccessor(i);
  234. MSchedGraphNode *dest = edge->getDest();
  235. if(branches.count(dest))
  236. newEdges.insert(std::make_pair(dest, startNode));
  237. //only visit if we have not already
  238. else if(!visited.count(dest)) {
  239. if(edge->getIteDiff() == 0)
  240. hasPath(dest, visited, branches, startNode, newEdges);}
  241. }
  242. }
  243. //Experimental code to add edges from the branch to all nodes dependent upon it.
  244. void MSchedGraph::addBranchEdges() {
  245. std::set<MSchedGraphNode*> branches;
  246. std::set<MSchedGraphNode*> nodes;
  247. for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
  248. I != E; ++I) {
  249. if(I->second->isBranch())
  250. if(I->second->hasPredecessors())
  251. branches.insert(I->second);
  252. }
  253. //See if there is a path first instruction to the branches, if so, add an
  254. //iteration dependence between that node and the branch
  255. std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> > newEdges;
  256. for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end();
  257. I != E; ++I) {
  258. std::set<MSchedGraphNode*> visited;
  259. hasPath((I->second), visited, branches, (I->second), newEdges);
  260. }
  261. //Spit out all edges we are going to add
  262. unsigned min = GraphMap.size();
  263. if(newEdges.size() == 1) {
  264. ((newEdges.begin())->first)->addOutEdge(((newEdges.begin())->second),
  265. MSchedGraphEdge::BranchDep,
  266. MSchedGraphEdge::NonDataDep, 1);
  267. }
  268. else {
  269. unsigned count = 0;
  270. MSchedGraphNode *start;
  271. MSchedGraphNode *end;
  272. for(std::set<std::pair<MSchedGraphNode*, MSchedGraphNode*> >::iterator I = newEdges.begin(), E = newEdges.end(); I != E; ++I) {
  273. DEBUG(std::cerr << "Branch Edge from: " << *(I->first) << " to " << *(I->second) << "\n");
  274. // if(I->second->getIndex() <= min) {
  275. start = I->first;
  276. end = I->second;
  277. //min = I->second->getIndex();
  278. //}
  279. start->addOutEdge(end,
  280. MSchedGraphEdge::BranchDep,
  281. MSchedGraphEdge::NonDataDep, 1);
  282. }
  283. }
  284. }
  285. //Add edges between the nodes
  286. void MSchedGraph::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs,
  287. DependenceAnalyzer &DA,
  288. std::map<MachineInstr*, Instruction*> &machineTollvm) {
  289. //Get Machine target information for calculating latency
  290. const TargetInstrInfo *MTI = Target.getInstrInfo();
  291. std::vector<MSchedGraphNode*> memInstructions;
  292. std::map<int, std::vector<OpIndexNodePair> > regNumtoNodeMap;
  293. std::map<const Value*, std::vector<OpIndexNodePair> > valuetoNodeMap;
  294. //Save PHI instructions to deal with later
  295. std::vector<const MachineInstr*> phiInstrs;
  296. unsigned index = 0;
  297. for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(),
  298. BE = BBs.end(); B != BE; ++B) {
  299. const MachineBasicBlock *BB = *B;
  300. //Loop over instructions in MBB and add nodes and edges
  301. for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
  302. MI != e; ++MI) {
  303. //Ignore indvar instructions
  304. if(ignoreInstrs.count(MI)) {
  305. ++index;
  306. continue;
  307. }
  308. //Get each instruction of machine basic block, get the delay
  309. //using the op code, create a new node for it, and add to the
  310. //graph.
  311. MachineOpCode opCode = MI->getOpcode();
  312. int delay;
  313. #if 0 // FIXME: LOOK INTO THIS
  314. //Check if subsequent instructions can be issued before
  315. //the result is ready, if so use min delay.
  316. if(MTI->hasResultInterlock(MIopCode))
  317. delay = MTI->minLatency(MIopCode);
  318. else
  319. #endif
  320. //Get delay
  321. delay = MTI->maxLatency(opCode);
  322. //Create new node for this machine instruction and add to the graph.
  323. //Create only if not a nop
  324. if(MTI->isNop(opCode))
  325. continue;
  326. //Sparc BE does not use PHI opcode, so assert on this case
  327. assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
  328. bool isBranch = false;
  329. //We want to flag the branch node to treat it special
  330. if(MTI->isBranch(opCode))
  331. isBranch = true;
  332. //Node is created and added to the graph automatically
  333. MSchedGraphNode *node = new MSchedGraphNode(MI, this, index, delay,
  334. isBranch);
  335. DEBUG(std::cerr << "Created Node: " << *node << "\n");
  336. //Check OpCode to keep track of memory operations to add memory
  337. //dependencies later.
  338. if(MTI->isLoad(opCode) || MTI->isStore(opCode))
  339. memInstructions.push_back(node);
  340. //Loop over all operands, and put them into the register number to
  341. //graph node map for determining dependencies
  342. //If an operands is a use/def, we have an anti dependence to itself
  343. for(unsigned i=0; i < MI->getNumOperands(); ++i) {
  344. //Get Operand
  345. const MachineOperand &mOp = MI->getOperand(i);
  346. //Check if it has an allocated register
  347. if(mOp.hasAllocatedReg()) {
  348. int regNum = mOp.getReg();
  349. if(regNum != SparcV9::g0) {
  350. //Put into our map
  351. regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
  352. }
  353. continue;
  354. }
  355. //Add virtual registers dependencies
  356. //Check if any exist in the value map already and create dependencies
  357. //between them.
  358. if(mOp.getType() == MachineOperand::MO_VirtualRegister
  359. || mOp.getType() == MachineOperand::MO_CCRegister) {
  360. //Make sure virtual register value is not null
  361. assert((mOp.getVRegValue() != NULL) && "Null value is defined");
  362. //Check if this is a read operation in a phi node, if so DO NOT PROCESS
  363. if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
  364. DEBUG(std::cerr << "Read Operation in a PHI node\n");
  365. continue;
  366. }
  367. if (const Value* srcI = mOp.getVRegValue()) {
  368. //Find value in the map
  369. std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
  370. = valuetoNodeMap.find(srcI);
  371. //If there is something in the map already, add edges from
  372. //those instructions
  373. //to this one we are processing
  374. if(V != valuetoNodeMap.end()) {
  375. addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
  376. //Add to value map
  377. V->second.push_back(std::make_pair(i,node));
  378. }
  379. //Otherwise put it in the map
  380. else
  381. //Put into value map
  382. valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
  383. }
  384. }
  385. }
  386. ++index;
  387. }
  388. //Loop over LLVM BB, examine phi instructions, and add them to our
  389. //phiInstr list to process
  390. const BasicBlock *llvm_bb = BB->getBasicBlock();
  391. for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
  392. I != E; ++I) {
  393. if(const PHINode *PN = dyn_cast<PHINode>(I)) {
  394. MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
  395. for (unsigned j = 0; j < tempMvec.size(); j++) {
  396. if(!ignoreInstrs.count(tempMvec[j])) {
  397. DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
  398. phiInstrs.push_back((MachineInstr*) tempMvec[j]);
  399. }
  400. }
  401. }
  402. }
  403. addMemEdges(memInstructions, DA, machineTollvm);
  404. addMachRegEdges(regNumtoNodeMap);
  405. //Finally deal with PHI Nodes and Value*
  406. for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(),
  407. E = phiInstrs.end(); I != E; ++I) {
  408. //Get Node for this instruction
  409. std::map<const MachineInstr*, MSchedGraphNode*>::iterator X;
  410. X = find(*I);
  411. if(X == GraphMap.end())
  412. continue;
  413. MSchedGraphNode *node = X->second;
  414. DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
  415. //Loop over operands for this instruction and add value edges
  416. for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
  417. //Get Operand
  418. const MachineOperand &mOp = (*I)->getOperand(i);
  419. if((mOp.getType() == MachineOperand::MO_VirtualRegister
  420. || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
  421. //find the value in the map
  422. if (const Value* srcI = mOp.getVRegValue()) {
  423. //Find value in the map
  424. std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
  425. = valuetoNodeMap.find(srcI);
  426. //If there is something in the map already, add edges from
  427. //those instructions
  428. //to this one we are processing
  429. if(V != valuetoNodeMap.end()) {
  430. addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
  431. phiInstrs, 1);
  432. }
  433. }
  434. }
  435. }
  436. }
  437. }
  438. }
  439. //Add dependencies for Value*s
  440. void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
  441. MSchedGraphNode *destNode, bool nodeIsUse,
  442. bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff) {
  443. for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
  444. E = NodesInMap.end(); I != E; ++I) {
  445. //Get node in vectors machine operand that is the same value as node
  446. MSchedGraphNode *srcNode = I->second;
  447. MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
  448. if(diff > 0)
  449. if(std::find(phiInstrs.begin(), phiInstrs.end(), srcNode->getInst()) == phiInstrs.end())
  450. continue;
  451. //Node is a Def, so add output dep.
  452. if(nodeIsDef) {
  453. if(mOp.isUse()) {
  454. DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=anti)\n");
  455. srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
  456. MSchedGraphEdge::AntiDep, diff);
  457. }
  458. if(mOp.isDef()) {
  459. DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=output)\n");
  460. srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
  461. MSchedGraphEdge::OutputDep, diff);
  462. }
  463. }
  464. if(nodeIsUse) {
  465. if(mOp.isDef()) {
  466. DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=true)\n");
  467. srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep,
  468. MSchedGraphEdge::TrueDep, diff);
  469. }
  470. }
  471. }
  472. }
  473. //Add dependencies for machine registers across iterations
  474. void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >& regNumtoNodeMap) {
  475. //Loop over all machine registers in the map, and add dependencies
  476. //between the instructions that use it
  477. typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
  478. for(regNodeMap::iterator I = regNumtoNodeMap.begin();
  479. I != regNumtoNodeMap.end(); ++I) {
  480. //Get the register number
  481. int regNum = (*I).first;
  482. //Get Vector of nodes that use this register
  483. std::vector<OpIndexNodePair> Nodes = (*I).second;
  484. //Loop over nodes and determine the dependence between the other
  485. //nodes in the vector
  486. for(unsigned i =0; i < Nodes.size(); ++i) {
  487. //Get src node operator index that uses this machine register
  488. int srcOpIndex = Nodes[i].first;
  489. //Get the actual src Node
  490. MSchedGraphNode *srcNode = Nodes[i].second;
  491. //Get Operand
  492. const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
  493. bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
  494. bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
  495. //Look at all instructions after this in execution order
  496. for(unsigned j=i+1; j < Nodes.size(); ++j) {
  497. //Sink node is a write
  498. if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
  499. //Src only uses the register (read)
  500. if(srcIsUse)
  501. srcNode->addOutEdge(Nodes[j].second,
  502. MSchedGraphEdge::MachineRegister,
  503. MSchedGraphEdge::AntiDep);
  504. else if(srcIsUseandDef) {
  505. srcNode->addOutEdge(Nodes[j].second,
  506. MSchedGraphEdge::MachineRegister,
  507. MSchedGraphEdge::AntiDep);
  508. srcNode->addOutEdge(Nodes[j].second,
  509. MSchedGraphEdge::MachineRegister,
  510. MSchedGraphEdge::OutputDep);
  511. }
  512. else
  513. srcNode->addOutEdge(Nodes[j].second,
  514. MSchedGraphEdge::MachineRegister,
  515. MSchedGraphEdge::OutputDep);
  516. }
  517. //Dest node is a read
  518. else {
  519. if(!srcIsUse || srcIsUseandDef)
  520. srcNode->addOutEdge(Nodes[j].second,
  521. MSchedGraphEdge::MachineRegister,
  522. MSchedGraphEdge::TrueDep);
  523. }
  524. }
  525. //Look at all the instructions before this one since machine registers
  526. //could live across iterations.
  527. for(unsigned j = 0; j < i; ++j) {
  528. //Sink node is a write
  529. if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
  530. //Src only uses the register (read)
  531. if(srcIsUse)
  532. srcNode->addOutEdge(Nodes[j].second,
  533. MSchedGraphEdge::MachineRegister,
  534. MSchedGraphEdge::AntiDep, 1);
  535. else if(srcIsUseandDef) {
  536. srcNode->addOutEdge(Nodes[j].second,
  537. MSchedGraphEdge::MachineRegister,
  538. MSchedGraphEdge::AntiDep, 1);
  539. srcNode->addOutEdge(Nodes[j].second,
  540. MSchedGraphEdge::MachineRegister,
  541. MSchedGraphEdge::OutputDep, 1);
  542. }
  543. else
  544. srcNode->addOutEdge(Nodes[j].second,
  545. MSchedGraphEdge::MachineRegister,
  546. MSchedGraphEdge::OutputDep, 1);
  547. }
  548. //Dest node is a read
  549. else {
  550. if(!srcIsUse || srcIsUseandDef)
  551. srcNode->addOutEdge(Nodes[j].second,
  552. MSchedGraphEdge::MachineRegister,
  553. MSchedGraphEdge::TrueDep,1 );
  554. }
  555. }
  556. }
  557. }
  558. }
  559. //Add edges between all loads and stores
  560. //Can be less strict with alias analysis and data dependence analysis.
  561. void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
  562. DependenceAnalyzer &DA,
  563. std::map<MachineInstr*, Instruction*> &machineTollvm) {
  564. //Get Target machine instruction info
  565. const TargetInstrInfo *TMI = Target.getInstrInfo();
  566. //Loop over all memory instructions in the vector
  567. //Knowing that they are in execution, add true, anti, and output dependencies
  568. for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
  569. MachineInstr *srcInst = (MachineInstr*) memInst[srcIndex]->getInst();
  570. //Get the machine opCode to determine type of memory instruction
  571. MachineOpCode srcNodeOpCode = srcInst->getOpcode();
  572. //All instructions after this one in execution order have an
  573. //iteration delay of 0
  574. for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) {
  575. //No self loops
  576. if(destIndex == srcIndex)
  577. continue;
  578. MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
  579. DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
  580. DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
  581. //Assuming instructions without corresponding llvm instructions
  582. //are from constant pools.
  583. if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst))
  584. continue;
  585. bool useDepAnalyzer = true;
  586. //Some machine loads and stores are generated by casts, so be
  587. //conservative and always add deps
  588. Instruction *srcLLVM = machineTollvm[srcInst];
  589. Instruction *destLLVM = machineTollvm[destInst];
  590. if(!isa<LoadInst>(srcLLVM)
  591. && !isa<StoreInst>(srcLLVM)) {
  592. if(isa<BinaryOperator>(srcLLVM)) {
  593. if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1)))
  594. continue;
  595. }
  596. useDepAnalyzer = false;
  597. }
  598. if(!isa<LoadInst>(destLLVM)
  599. && !isa<StoreInst>(destLLVM)) {
  600. if(isa<BinaryOperator>(destLLVM)) {
  601. if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1)))
  602. continue;
  603. }
  604. useDepAnalyzer = false;
  605. }
  606. //Use dep analysis when we have corresponding llvm loads/stores
  607. if(useDepAnalyzer) {
  608. bool srcBeforeDest = true;
  609. if(destIndex < srcIndex)
  610. srcBeforeDest = false;
  611. DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst],
  612. machineTollvm[destInst],
  613. srcBeforeDest);
  614. for(std::vector<Dependence>::iterator d = dr.dependences.begin(),
  615. de = dr.dependences.end(); d != de; ++d) {
  616. //Add edge from load to store
  617. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  618. MSchedGraphEdge::MemoryDep,
  619. d->getDepType(), d->getIteDiff());
  620. }
  621. }
  622. //Otherwise, we can not do any further analysis and must make a dependence
  623. else {
  624. //Get the machine opCode to determine type of memory instruction
  625. MachineOpCode destNodeOpCode = destInst->getOpcode();
  626. //Get the Value* that we are reading from the load, always the first op
  627. const MachineOperand &mOp = srcInst->getOperand(0);
  628. const MachineOperand &mOp2 = destInst->getOperand(0);
  629. if(mOp.hasAllocatedReg())
  630. if(mOp.getReg() == SparcV9::g0)
  631. continue;
  632. if(mOp2.hasAllocatedReg())
  633. if(mOp2.getReg() == SparcV9::g0)
  634. continue;
  635. DEBUG(std::cerr << "Adding dependence for machine instructions\n");
  636. //Load-Store deps
  637. if(TMI->isLoad(srcNodeOpCode)) {
  638. if(TMI->isStore(destNodeOpCode))
  639. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  640. MSchedGraphEdge::MemoryDep,
  641. MSchedGraphEdge::AntiDep, 0);
  642. }
  643. else if(TMI->isStore(srcNodeOpCode)) {
  644. if(TMI->isStore(destNodeOpCode))
  645. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  646. MSchedGraphEdge::MemoryDep,
  647. MSchedGraphEdge::OutputDep, 0);
  648. else
  649. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  650. MSchedGraphEdge::MemoryDep,
  651. MSchedGraphEdge::TrueDep, 0);
  652. }
  653. }
  654. }
  655. }
  656. }