CACAO
MachineInstructionSchedulingPass.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/MachineInstructionSchedulingPass.cpp - MachineInstructionSchedulingPass
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
34 
35 #include "Target.hpp"
36 
37 #include "toolbox/logging.hpp"
38 
39 #define DEBUG_NAME "compiler2/MachineInstructionSchedulingPass"
40 
41 namespace cacao {
42 namespace jit {
43 namespace compiler2 {
44 
45 namespace {
46 
47 struct UpdatePhiOperand : public std::unary_function<MachinePhiInst*,void> {
48  typedef alloc::map<Instruction*,MachineOperand*>::type InstMapTy;
49  InstMapTy inst_map;
50  /// constructor
51  UpdatePhiOperand(InstMapTy &inst_map) : inst_map(inst_map) {}
52  /// function operator
53  virtual void operator()(MachinePhiInst* phi) const {
54  PHIInst* phi_inst = phi->get_PHIInst();
55  assert(phi_inst);
56  Instruction::const_op_iterator op = phi_inst->op_begin();
57 
58  for (MachineInstruction::operand_iterator i = phi->begin(),
59  e = phi->end(); i != e; ++i) {
60  Instruction *I = (*op)->to_Instruction();
61  assert(I);
62  InstMapTy::const_iterator it = inst_map.find(I);
63  assert(it != inst_map.end());
64  // set operand
65  i->op = it->second;
66  ++op;
67  }
68  }
69 };
70 
71 } // end anonymous namespace
72 
74  BasicBlockSchedule *BS = get_Pass<BasicBlockSchedulingPass>();
75 #if !PATTERN_MATCHING
76  ListSchedulingPass* IS = get_Pass<ListSchedulingPass>();
77 #else
78  GlobalSchedule* GS = get_Pass<ScheduleClickPass>();
79 #endif
80 
82 
83  // create machine basic blocks
85  e = BS->bb_end(); i != e ; ++i) {
86  BeginInst *BI = *i;
87  assert(BI);
88  // create MachineBasicBlock
90  map[BI] = MBB;
91  }
92 
93  Backend *BE = JD.get_Backend();
95 
96  // lower instructions
98  e = BS->bb_end(); i != e ; ++i) {
99 
100  BeginInst *BI = *i;
101  MachineBasicBlock *MBB = map[BI];
102  LoweringVisitor LV(BE,MBB,map,inst_map,this);
103 
104 #if !PATTERN_MATCHING
105  LOG2("lowering for BB using list sched " << BI << nl);
107  e = IS->inst_end(BI); i != e; ++i) {
108  Instruction *I = *i;
109  LOG2("lower: " << *I << nl);
110  I->accept(LV, true);
111  }
112 #else
113  LOG2("Lowering with Pattern Matching " << BI << nl);
114  Matcher M(GS, BI, &LV);
115  M.run();
116 #endif
117  // fix predecessors
119  e = BI->pred_end(); i != e; ++i) {
120  BeginInst *pred = (*i)->get_BeginInst();
122  assert(it != map.end());
123  MBB->insert_pred(it->second);
124  }
125 
126  }
127 
128  for (const_iterator i = begin(), e = end(); i != e; ++i) {
129  MachineBasicBlock *MBB = *i;
130  LOG2("MBB: " << *MBB << nl);
131  // fix phi instructions
132  UpdatePhiOperand functor(inst_map);
133  std::for_each(MBB->phi_begin(), MBB->phi_end(), functor);
134  // split basic blocks
135  for (MachineBasicBlock::iterator i = MBB->begin(), e = MBB->end();
136  i != e; ) {
137  MachineInstruction *MI = *i;
138  ++i;
139  if (MI->is_jump() && i != e) {
141  assert(new_MBB);
142  new_MBB->insert_pred(MBB);
143  new_MBB->push_front(new MachineLabelInst());
144  LOG2("new MBB: " << *new_MBB << nl);
145  move_instructions(i,e,*MBB,*new_MBB);
146  break;
147  }
148  }
149  }
150  return true;
151 }
152 
153 // verify
156  i != e; ++i) {
157  MachineBasicBlock *MBB = *i;
158  if(MBB->size() == 0) {
159  ERROR_MSG("verification failed", "MachineBasicBlock ("
160  << *MBB << ") empty");
161  return false;
162  }
163  MachineInstruction *front = MBB->front();
164  // check for label
165  if(!front->is_label()) {
166  ERROR_MSG("verification failed", "first Instruction ("
167  << *front << ") not a label");
168  return false;
169  }
170  MachineInstruction *back = MBB->back();
171  // check for end
172  if(!back->is_end()) {
173  ERROR_MSG("verification failed", "last Instruction ("
174  << *back << ") not a control flow transfer instruction");
175  return false;
176  }
177 
178  std::size_t num_pred = MBB->pred_size();
179  // check phis
181  i != e; ++i) {
182  MachinePhiInst *phi = *i;
183  if (phi->op_size() != num_pred) {
184  ERROR_MSG("verification failed", "Machine basic block (" << *MBB << ") has "
185  << num_pred << " predecessors but phi node (" << *phi << ") has " << phi->op_size());
186  return false;
187  }
188  }
189 
190  for (MachineBasicBlock::const_iterator i = MBB->begin(), e = MBB->end();
191  i != e ; ++i) {
192  MachineInstruction *MI = *i;
193  // check for block
194  if(!MI->get_block()) {
195  ERROR_MSG("No block", *MI);
196  return false;
197  }
198  }
199  }
200  return true;
201 }
202 
203 // pass usage
208  return PU;
209 }
210 
211 // register pass
212 static PassRegistry<MachineInstructionSchedulingPass> X("MachineInstructionSchedulingPass");
213 
214 // LIST SCHEDULING PART MOVED HERE
215 
216 } // end namespace compiler2
217 } // end namespace jit
218 } // end namespace cacao
219 
220 
221 /*
222  * These are local overrides for various environment variables in Emacs.
223  * Please do not remove this and leave it at the end of the file, where
224  * Emacs will automagically detect them.
225  * ---------------------------------------------------------------------
226  * Local variables:
227  * mode: c++
228  * indent-tabs-mode: t
229  * c-basic-offset: 4
230  * tab-width: 4
231  * End:
232  * vim:noexpandtab:sw=4:ts=4:
233  */
GlobalSchedule TODO: more info.
ordered const_iterator
const_phi_iterator phi_end() const
returns an const iterator to the phi instructions
BeginInst * BI
PredecessorListTy::const_iterator const_pred_iterator
This Instruction marks the start of a basic block.
u2 op
Definition: disass.cpp:129
A basic block of (scheduled) machine instructions.
virtual void accept(InstructionVisitor &v, bool copyOperands)=0
Visitor pattern.
MBBIterator self_iterator() const
get self iterator
void move_instructions(InputIterator first, InputIterator last, MachineBasicBlock &from, MachineBasicBlock &to)
Move instructions to another basic block.
iterator end()
returns an iterator to the end
ordered iterator
#define ERROR_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:124
iterator begin()
returns an iterator to the beginning
virtual PassUsage & get_PassUsage(PassUsage &PA) const
Set the requirements for the pass.
const_pred_iterator pred_begin() const
std::size_t size() const
returns the number of elements
const_phi_iterator phi_begin() const
returns an const iterator to the phi instructions
OperandListTy::const_iterator const_op_iterator
Definition: Instruction.hpp:82
const_reference front() const
access the first element
const_reference back() const
access the last element
iterator begin()
returns an iterator to the beginning
Stores the interdependencies of a pass.
Definition: PassUsage.hpp:55
std::size_t pred_size() const
returns the number of predecessor nodes
void push_front(MachineInstruction *value)
inserts value to the beginning
Instruction super class.
Definition: Instruction.hpp:75
MIIterator i
MachineInstructionSchedule::iterator insert_after(iterator pos, const MBBBuilder &value)
inserts value after the element pointed to by pos
#define LOG2(STMT)
Definition: logging.hpp:93
MIIterator e
Proxy to encode explicit and implicit successors.
#define I(value)
Definition: codegen.c:279
jmethodID jint const void jint const jvmtiAddrLocationMap * map
Definition: jvmti.h:338
const GlobalSchedule * GS
const_pred_iterator pred_end() const
const Method & M
BasicBlockListTy::const_iterator const_bb_iterator
BasicBlockSchedulingPass TODO: more info.
void insert_pred(MachineBasicBlock *value)
Appends the given element value to the list of predecessors.
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
Nl nl
Definition: OStream.cpp:56
BasicBlockSchedule TODO: more info.
MachineInstructionSchedule::iterator push_back(const MBBBuilder &value)
Appends the given element value to the end of the container.
void add_requires()
PassName is required.
Definition: PassUsage.hpp:78
InstructionSchedule TODO: more info.
virtual BeginInst * get_BeginInst() const
Get the corresponding BeginInst.