38 #define DEBUG_NAME "compiler2/GlobalValueNumberingPass"
42 "globalvaluenumberingpass","globalvaluenumberingpass",compiler2_stat)
44 "total number of CONSTInst nodes",compiler2_globalvaluenumberingpass_stat)
46 "total number of arithmetical nodes",compiler2_globalvaluenumberingpass_stat)
48 "total number of PHIInst nodes",compiler2_globalvaluenumberingpass_stat)
50 "total number of ARRAYBOUNDSCHECKInst nodes",compiler2_globalvaluenumberingpass_stat)
52 "number of redundant CONSTInst nodes",compiler2_globalvaluenumberingpass_stat)
54 "number of redundant arithmetical nodes",compiler2_globalvaluenumberingpass_stat)
56 "number of redundant PHIInst nodes",compiler2_globalvaluenumberingpass_stat)
58 "number of redundant ARRAYBOUNDSCHECKInst nodes",compiler2_globalvaluenumberingpass_stat)
61 if ((INST)->get_opcode() == Instruction::CONSTInstID) {
\
63 }
else if ((INST)->is_arithmetic()) {
\
65 }
else if ((INST)->get_opcode() == Instruction::PHIInstID) {
\
67 }
else if ((INST)->get_opcode() == Instruction::ARRAYBOUNDSCHECKInstID) {
\
70 #define STAT_TOTAL_NODES(INST) STAT_NODE_COUNT_HELPER(INST, 1, total)
71 #define STAT_REDUNDANT_NODES(INST, CNT) STAT_NODE_COUNT_HELPER(INST, CNT, redundant)
92 if (I->has_side_effects()
94 || I->get_opcode() == Instruction::LOADInstID
95 || I->get_opcode() == Instruction::ALOADInstID
96 || I->get_opcode() == Instruction::SourceStateInstID
97 || I->get_opcode() == Instruction::DeoptimizeInstID
98 || I->get_opcode() == Instruction::AssumptionInstID
99 || I->get_opcode() == Instruction::CHECKNULLInstID) {
106 CONSTInst *constInst = I->to_CONSTInst();
111 switch (constInst->get_type()) {
114 constInst->get_Int());
118 constInst->get_Long());
122 constInst->get_Float());
126 constInst->get_Double());
138 PHIInst *phiInst = I->to_PHIInst();
140 BeginInst *bb = phiInst->get_BeginInst();
143 && !I->to_EndInst()) {
176 BlockTy::const_iterator
i = block->begin();
195 for (PartitionTy::const_iterator
i =
partition.begin(),
199 for (
int operandIndex = 0; operandIndex <
max_arity; operandIndex++) {
203 pair->second = operandIndex;
215 if (!inverseVector) {
220 inverseVector->push_back(users);
223 return (*inverseVector)[op_index];
231 oe = I->
op_end(); oi != oe; oi++) {
244 flags =
new std::vector<bool>(
max_arity);
252 (*flags)[
index] = flag;
257 return (*flags)[
index];
264 pair->second =
index;
291 assert(block->size() > instructions->size());
295 for (TouchedInstListTy::const_iterator
i = instructions->begin(),
296 e = instructions->end();
i !=
e;
i++) {
302 for (
int operandIndex = 0; operandIndex <
max_arity; operandIndex++) {
304 && block->size() <= new_block->size()) {
313 for (PartitionTy::const_iterator
i =
partition.begin(),
316 if (block->size() > 1) {
335 for (
auto i =
std::next(block->begin());
i != block->end();
i++) {
342 dependent->append_dep(inst);
343 dependent->remove_dep(replacable);
350 for (TouchedInstListTy::const_iterator
i = instructions->begin(),
351 e = instructions->end();
i !=
e;
i++) {
359 for (BlockTy::const_iterator
i = block->begin(),
360 e = block->end();
i !=
e;
i++) {
369 for (PartitionTy::const_iterator
i =
partition.begin(),
371 LOG(
"=============================================================" <<
nl);
379 template <
typename T>
381 while (!lst->empty()) {
387 template <
typename T1,
typename T2,
typename Iterator>
396 template <
typename T1,
typename T2>
420 LOG(
"BEFORE PARTITIONING" <<
nl);
425 BlockTy *block = workListPair->first;
426 int operandIndex = workListPair->second;
429 std::list<BlockTy*> touched;
431 for (BlockTy::const_iterator
i = block->begin(),
432 e = block->end();
i !=
e;
i++) {
436 for (InstructionListTy::const_iterator ui = usersForIndex->begin(),
437 ue = usersForIndex->end(); ui != ue; ui++) {
443 touched.push_back(userBlock);
446 touchedInstructions->insert(user);
453 for (std::list<BlockTy*>::const_iterator
i = touched.begin(),
454 e = touched.end();
i !=
e;
i++) {
458 if (touchedInstructions->size() > 0
459 && touchedBlock->size() != touchedInstructions->size()) {
460 LOG(
"split block (" << touchedBlock->size() <<
", " << touchedInstructions->size() <<
")" <<
nl);
464 split(touchedBlock, touchedInstructions);
466 touchedInstructions->clear();
470 LOG(
nl <<
"AFTER PARTITIONING" <<
nl);
BlockTy * get_block(Instruction *inst)
std::unordered_map< int32_t, BlockTy * > IntBlockMapTy
#define STATISTICS(x)
Wrapper for statistics only code.
std::unordered_map< Instruction::InstID, BlockTy *, std::hash< int > > OpcodeBlockMapTy
these types are needed for the creation of the inital blocks
const_dep_iterator rdep_begin() const
#define STAT_REGISTER_SUBGROUP(var, name, description, group)
Register a statistics group and add it to a group.
void init_worklist_and_touchedblocks()
virtual CONSTInst * to_CONSTInst()
void eliminate_redundancies()
alloc::unordered_set< Instruction * >::type BlockTy
InstructionListTy * get_users(Instruction *inst, int op_index)
std::list< Instruction * > InstructionListTy
alloc::unordered_set< Instruction * >::type TouchedInstListTy
Inst2BlockMapTy inst2BlockMap
OperandListTy::const_iterator const_op_iterator
void add_schedule_before()
Schedule before PassName.
virtual bool run(JITData &JD)
Run the Pass.
bool is_in_worklist(BlockTy *block, int index)
void replace_value(Value *v)
Replace this Value this the new one in all users.
void set_in_worklist(BlockTy *block, int index, bool flag)
#define STAT_REDUNDANT_NODES(INST, CNT)
std::vector< bool > * get_worklist_flags(BlockTy *block)
std::vector< T, Allocator< T > > type
BlockTy * get_or_create_block(T1 &map, T2 key)
Stores the interdependencies of a pass.
void init_operand_inverse(Method::const_iterator begin, Method::const_iterator end)
#define STAT_REGISTER_GROUP_VAR(type, var, init, name, description, group)
Register an statistics variable and add it to a group.
std::unordered_map< int64_t, BlockTy * > LongBlockMapTy
Block2TouchedInstListMapTy block2TouchedInstListMap
virtual Instruction * to_Instruction()
void split(BlockTy *block, TouchedInstListTy *instructions)
std::unordered_map< double, BlockTy * > DoubleBlockMapTy
void delete_in_range(std::unordered_map< T1, T2 > *map, Iterator begin, Iterator end)
const_dep_iterator rdep_end() const
void add_to_worklist(BlockTy *block, int operandIndex)
std::pair< BlockTy *, int > WorkListPairTy
InstructionListTy::const_iterator const_iterator
const_iterator end() const
const_op_iterator op_begin() const
static int arity(BlockTy *block)
std::vector< InstructionListTy * > OperandIndex2UsersTy
OperandInverseMapTy operandInverseMap
#define LOG(STMT)
Analogous to DEBUG.
void print_block(BlockTy *block)
static int compute_max_arity(Method::const_iterator begin, Method::const_iterator end)
jmethodID jint const void jint const jvmtiAddrLocationMap * map
#define STAT_TOTAL_NODES(INST)
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
const_iterator begin() const
TouchedInstListTy * get_touched_instructions(BlockTy *block)
void init_partition(Method::const_iterator begin, Method::const_iterator end)
void add_to_block(BlockTy *block, Instruction *inst)
virtual PassUsage & get_PassUsage(PassUsage &PU) const
Set the requirements for the pass.
void clean_up_operand_inverse()
static java_object_t * next
std::unordered_map< float, BlockTy * > FloatBlockMapTy
std::unordered_map< BeginInst *, BlockTy * > BBBlockMapTy
WorkListPairTy * selectAndDeleteFromWorkList()
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
BlockTy * create_block()
creates and returns a new block and does some setup work needed for the further execution of the part...
void print_instructions(TouchedInstListTy *instructions)
void eliminate_redundancies_in_block(BlockTy *block)
const_op_iterator op_end() const
void add_requires()
PassName is required.
static Option< bool > enabled
#define STAT_NODE_COUNT_HELPER(INST, CNT, INFIX)