CACAO
MachineBasicBlock.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/MachineBasicBlock.cpp - MachineBasicBlock
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 
28 #include "toolbox/OStream.hpp"
29 
30 #include "toolbox/logging.hpp"
31 #define DEBUG_NAME "compiler2/MachineBasicBlock"
32 
33 namespace cacao {
34 namespace jit {
35 namespace compiler2 {
36 
38  static _iterator e;
39  return e;
40 }
41 
42 std::size_t MachineBasicBlock::id_counter = 0;
43 
45  return OS << "MBB:" << setz(4) << id;
46 }
47 
49  MI->set_block(this);
50 }
51 
53  if (MI->is_jump()) {
55  e = MI->successor_end(); i != e; ++i) {
56  MachineBasicBlock *MBB = *i;
58  e = MBB->pred_end(); i != e; ++i) {
59  if (**i == from) {
60  LOG("Instruction " << *MI << " moved from " << from
61  << " to " << to << " predecessor of MBB: " << *MBB << nl);
62  *i = &to;
63  }
64  }
65  }
66  }
67 }
68 
70  return value->is_phi();
71 }
72 
74  if (it.is_end())
75  return OS << "MIIterator end";
76  return OS << *it;
77 }
78 
79 namespace {
80 
81 struct TargetOperandEqualPred
82  : public std::unary_function<MachineInstruction*,bool> {
83  MachineOperand *op;
84  /// constructor
85  TargetOperandEqualPred(MachineOperand *op) : op(op) {}
86  /// function call operand
87  bool operator()(MachineInstruction* MI) {
88  return MI->get_result().op == op;
89  }
90 };
91 
92 } // end anonymous namespace
93 
95  MachineOperand* op) {
97  = std::find_if(MBB->phi_begin(), MBB->phi_end(), TargetOperandEqualPred(op));
98  if (it != MBB->phi_end())
99  return *it;
100  return NULL;
101 }
102 
104  Backend *backend) {
105  assert(from->get_parent() == to->get_parent());
106  MachineInstructionSchedule *MIS = from->get_parent();
107  // create new block
108  MachineBasicBlock *MBB = *MIS->insert_after(from->self_iterator(),MBBBuilder());
109  MBB->push_front(new MachineLabelInst());
110  MBB->push_back(backend->create_Jump(to));
111  // fix links (from -> new)
112  {
113  MachineInstruction *jump = from->back();
115  std::find(jump->successor_begin(),jump->successor_end(), to);
116  assert(i != jump->successor_end());
117  *i = MBB;
118  }
119  // fix links (new -> to)
120  {
122  std::find(to->pred_begin(), to->pred_end(),from);
123  assert(i!= to->pred_end());
124  *i = MBB;
125  }
126  return MBB;
127 }
128 
130  Backend *backend) {
131  #if !defined(NDEBUG)
132  MachineInstruction *jump = from->back();
133  // sanity checks
134  assert(std::find(jump->successor_begin(),jump->successor_end(), to)
135  != jump->successor_end());
136  assert(std::find(to->pred_begin(), to->pred_end(),from) != to->pred_end());
137  #endif
138 
139  return get_edge_block(from,to,backend)->mi_last();
140 }
141 
142 #if 0
143 std::insert_iterator<MachineBasicBlock> get_edge_inserter(
144  MachineBasicBlock *from, MachineBasicBlock *to) {
145  MIIterator last = get_edge_iterator(from,to);
146  return std::inserter(*last.block_it(), last);
147 }
148 #endif
149 
150 
152  MachineBasicBlock *MBB = (*pos)->get_block();
153  return MBB->convert(MBB->insert_before(MachineBasicBlock::convert(pos), value));
154 }
156  MachineBasicBlock *MBB = (*pos)->get_block();
157  return MBB->convert(MBB->insert_after(MachineBasicBlock::convert(pos), value));
158 }
159 
160 } // end namespace compiler2
161 } // end namespace jit
162 } // end namespace cacao
163 
164 
165 /*
166  * These are local overrides for various environment variables in Emacs.
167  * Please do not remove this and leave it at the end of the file, where
168  * Emacs will automagically detect them.
169  * ---------------------------------------------------------------------
170  * Local variables:
171  * mode: c++
172  * indent-tabs-mode: t
173  * c-basic-offset: 4
174  * tab-width: 4
175  * End:
176  * vim:noexpandtab:sw=4:ts=4:
177  */
void update(MachineInstruction *MI)
update instruction block
const_pred_iterator pred_end() const
returns an const iterator to the predecessors
const_phi_iterator phi_end() const
returns an const iterator to the phi instructions
MIIterator get_edge_iterator(MachineBasicBlock *from, MachineBasicBlock *to, Backend *backend)
bool check_is_phi(MachineInstruction *value)
iterator insert_before(iterator pos, MachineInstruction *value)
inserts value before the element pointed to by pos
argument_type from
MachinePhiInst * get_phi_from_operand(MachineBasicBlock *MBB, MachineOperand *op)
MIIterator mi_last()
returns an MIIterator to the last element (included)
u2 op
Definition: disass.cpp:129
A basic block of (scheduled) machine instructions.
virtual void set_block(MachineBasicBlock *MBB)
MBBIterator self_iterator() const
get self iterator
MIIterator insert_before(MIIterator pos, MachineInstruction *value)
Get an edge inserter.
ordered iterator
const_phi_iterator phi_begin() const
returns an const iterator to the phi instructions
virtual MachineInstruction * create_Jump(MachineBasicBlock *target) const =0
const_reference back() const
access the last element
void push_back(MachineInstruction *value)
Appends the given element value to the end of the container.
successor_list::const_iterator const_successor_iterator
const_pred_iterator pred_begin() const
returns an const iterator to the predecessors
Simple stream class for formatted output.
Definition: OStream.hpp:141
void push_front(MachineInstruction *value)
inserts value to the beginning
MachineBasicBlock * get_edge_block(MachineBasicBlock *from, MachineBasicBlock *to, Backend *backend)
get a new basic block for a given edge
OStream & operator<<(OStream &OS, const Conditional::CondID &cond)
Definition: Conditional.cpp:34
MIIterator i
MachineInstructionSchedule * get_parent() const
get parent
MIIterator pos
OStream & OS
MIIterator e
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
Proxy to encode explicit and implicit successors.
OStream & print(OStream &OS) const
print
MIIterator convert(iterator pos)
get a MIIterator form a iterator
Operands that can be directly used by the machine (register, memory, stackslot)
MIIterator insert_after(MIIterator pos, MachineInstruction *value)
void operator()(MachineInstruction *MI)
iterator insert_after(iterator pos, MachineInstruction *value)
inserts value after the element pointed to by pos
Nl nl
Definition: OStream.cpp:56
static SetZero setz(size_t w)
Definition: OStream.hpp:398