-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhighlevel_defuse.cpp
More file actions
57 lines (45 loc) · 1.46 KB
/
highlevel_defuse.cpp
File metadata and controls
57 lines (45 loc) · 1.46 KB
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
#include <cassert>
#include <set>
#include "instruction.h"
#include "operand.h"
#include "highlevel.h"
#include "highlevel_defuse.h"
namespace {
// High-level opcodes that do NOT have a destination operand
const std::set<HighLevelOpcode> NO_DEST = {
HINS_nop,
HINS_ret,
HINS_jmp,
HINS_call,
HINS_enter,
HINS_leave,
HINS_cjmp_t,
HINS_cjmp_f,
};
// Does the instruction have a destination operand?
bool has_dest_operand(HighLevelOpcode hl_opcode) {
return NO_DEST.count(hl_opcode) == 0;
}
}
namespace HighLevel {
// A high-level instruction is a def if it has a destination operand,
// and the destination operand is a vreg.
bool is_def(Instruction *ins) {
if (!has_dest_operand(HighLevelOpcode(ins->get_opcode())))
return false;
assert(ins->get_num_operands() > 0);
Operand dest = ins->get_operand(0);
return dest.get_kind() == Operand::VREG;
}
bool is_use(Instruction *ins, unsigned operand_index) {
Operand operand = ins->get_operand(operand_index);
if (operand_index == 0 && has_dest_operand(HighLevelOpcode(ins->get_opcode()))) {
// special case: if the instruction has a destination operand, but the operand
// is a memory reference, then the base register and index register (if either
// are present) are refs
return operand.is_memref() && (operand.has_base_reg() || operand.has_index_reg());
}
// in general, an operand is a ref if it mentions a virtual register
return operand.has_base_reg() || operand.has_index_reg();
}
}