aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.h
blob: 263a6130de67cde7360a1f67cd3599bd1511d0b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//===-- ModuloScheduling.h - Swing Modulo Scheduling------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_MODULOSCHEDULING_H
#define LLVM_MODULOSCHEDULING_H

#include "MSchedGraph.h"
#include "MSSchedule.h"
#include "llvm/Function.h"
#include "llvm/Pass.h"
#include "DependenceAnalyzer.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include <set>

namespace llvm {


  //Struct to contain ModuloScheduling Specific Information for each node
  struct MSNodeAttributes {
    int ASAP; //Earliest time at which the opreation can be scheduled
    int ALAP; //Latest time at which the operation can be scheduled.
    int MOB;
    int depth;
    int height;
    MSNodeAttributes(int asap=-1, int alap=-1, int mob=-1,
			     int d=-1, int h=-1) : ASAP(asap), ALAP(alap),
						   MOB(mob), depth(d),
						   height(h) {}
  };


  class ModuloSchedulingPass : public FunctionPass {
    const TargetMachine &target;

    //Map to hold Value* defs
    std::map<const Value*, MachineInstr*> defMap;

    //Map to hold list of instructions associate to the induction var for each BB
    std::map<const MachineBasicBlock*, std::map<const MachineInstr*, unsigned> > indVarInstrs;

    //Map to hold machine to  llvm instrs for each valid BB
    std::map<const MachineBasicBlock*, std::map<MachineInstr*, Instruction*> > machineTollvm;

    //LLVM Instruction we know we can add TmpInstructions to its MCFI
    Instruction *defaultInst;

    //Map that holds node to node attribute information
    std::map<MSchedGraphNode*, MSNodeAttributes> nodeToAttributesMap;

    //Map to hold all reccurrences
    std::set<std::pair<int, std::vector<MSchedGraphNode*> > > recurrenceList;

    //Set of edges to ignore, stored as src node and index into vector of successors
    std::set<std::pair<MSchedGraphNode*, unsigned> > edgesToIgnore;

    //Vector containing the partial order
    std::vector<std::set<MSchedGraphNode*> > partialOrder;

    //Vector containing the final node order
    std::vector<MSchedGraphNode*> FinalNodeOrder;

    //Schedule table, key is the cycle number and the vector is resource, node pairs
    MSSchedule schedule;

    //Current initiation interval
    int II;

    //Internal functions
    bool CreateDefMap(MachineBasicBlock *BI);
    bool MachineBBisValid(const MachineBasicBlock *BI);
    bool assocIndVar(Instruction *I, std::set<Instruction*> &indVar,
		     std::vector<Instruction*> &stack, BasicBlock *BB);
    int calculateResMII(const MachineBasicBlock *BI);
    int calculateRecMII(MSchedGraph *graph, int MII);
    void calculateNodeAttributes(MSchedGraph *graph, int MII);

    bool ignoreEdge(MSchedGraphNode *srcNode, MSchedGraphNode *destNode);

    int calculateASAP(MSchedGraphNode *node, int MII,MSchedGraphNode *destNode);
    int calculateALAP(MSchedGraphNode *node, int MII, int maxASAP, MSchedGraphNode *srcNode);

    int calculateHeight(MSchedGraphNode *node,MSchedGraphNode *srcNode);
    int calculateDepth(MSchedGraphNode *node, MSchedGraphNode *destNode);

    int findMaxASAP();
    void orderNodes();
    void findAllReccurrences(MSchedGraphNode *node,
			     std::vector<MSchedGraphNode*> &visitedNodes, int II);
    void addReccurrence(std::vector<MSchedGraphNode*> &recurrence, int II, MSchedGraphNode*, MSchedGraphNode*);

    void findAllCircuits(MSchedGraph *MSG, int II);
    bool circuit(MSchedGraphNode *v, std::vector<MSchedGraphNode*> &stack,
		 std::set<MSchedGraphNode*> &blocked,
		 std::vector<MSchedGraphNode*> &SCC, MSchedGraphNode *s,
		 std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B, int II,
		 std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes);

    void unblock(MSchedGraphNode *u, std::set<MSchedGraphNode*> &blocked,
		 std::map<MSchedGraphNode*, std::set<MSchedGraphNode*> > &B);

    void addRecc(std::vector<MSchedGraphNode*> &stack, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes);

    void searchPath(MSchedGraphNode *node, 
		    std::vector<MSchedGraphNode*> &path,
		    std::set<MSchedGraphNode*> &nodesToAdd,
		    std::set<MSchedGraphNode*> &new_reccurence);

    void pathToRecc(MSchedGraphNode *node,
		    std::vector<MSchedGraphNode*> &path,
		    std::set<MSchedGraphNode*> &poSet, std::set<MSchedGraphNode*> &lastNodes);

    void computePartialOrder();

    bool computeSchedule(const MachineBasicBlock *BB, MSchedGraph *MSG);
    bool scheduleNode(MSchedGraphNode *node, 
		      int start, int end);

    void predIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult);
    void succIntersect(std::set<MSchedGraphNode*> &CurrentSet, std::set<MSchedGraphNode*> &IntersectResult);

    void reconstructLoop(MachineBasicBlock*);

    //void saveValue(const MachineInstr*, const std::set<Value*>&, std::vector<Value*>*);

    void fixBranches(std::vector<MachineBasicBlock *> &prologues, std::vector<BasicBlock*> &llvm_prologues, MachineBasicBlock *machineBB, BasicBlock *llvmBB, std::vector<MachineBasicBlock *> &epilogues, std::vector<BasicBlock*> &llvm_epilogues, MachineBasicBlock*);

    void writePrologues(std::vector<MachineBasicBlock *> &prologues, MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_prologues, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation);

    void writeEpilogues(std::vector<MachineBasicBlock *> &epilogues, const MachineBasicBlock *origBB, std::vector<BasicBlock*> &llvm_epilogues, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave,std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation,  std::map<Value*, std::map<int, Value*> > &kernelPHIs);


    void writeKernel(BasicBlock *llvmBB, MachineBasicBlock *machineBB, std::map<const Value*, std::pair<const MachineInstr*, int> > &valuesToSave, std::map<Value*, std::map<int, Value*> > &newValues, std::map<Value*, MachineBasicBlock*> &newValLocation, std::map<Value*, std::map<int, Value*> > &kernelPHIs);

    void removePHIs(const MachineBasicBlock *origBB, std::vector<MachineBasicBlock *> &prologues, std::vector<MachineBasicBlock *> &epilogues, MachineBasicBlock *kernelBB, std::map<Value*, MachineBasicBlock*> &newValLocation);

    void connectedComponentSet(MSchedGraphNode *node, std::set<MSchedGraphNode*> &ccSet, std::set<MSchedGraphNode*> &lastNodes);

  public:
    ModuloSchedulingPass(TargetMachine &targ) : target(targ) {}
    virtual bool runOnFunction(Function &F);
    virtual const char* getPassName() const { return "ModuloScheduling"; }

    // getAnalysisUsage
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      /// HACK: We don't actually need loopinfo or scev, but we have
      /// to say we do so that the pass manager does not delete it
      /// before we run.
      AU.addRequired<LoopInfo>();
      AU.addRequired<ScalarEvolution>();
      
      AU.addRequired<DependenceAnalyzer>();
    }

  };

}


#endif