Fix pointer addition
[smatch.git] / linearize.h
blob8c7ca63b409e49ca73fc53845c82f26f454e6f98
1 #ifndef LINEARIZE_H
2 #define LINEARIZE_H
4 #include "lib.h"
5 #include "token.h"
6 #include "parse.h"
7 #include "symbol.h"
9 /* Silly pseudo define. Do this right some day */
10 struct pseudo {
11 int nr;
14 typedef struct pseudo *pseudo_t;
16 #define VOID NULL
18 struct multijmp {
19 struct basic_block *target;
20 int begin, end;
23 struct phi {
24 struct basic_block *source;
25 pseudo_t pseudo;
28 struct instruction {
29 struct symbol *type;
30 int opcode;
31 union {
32 pseudo_t target;
33 pseudo_t cond; /* for branch and switch */
35 union {
36 struct /* branch */ {
37 struct basic_block *bb_true, *bb_false;
39 struct /* switch */ {
40 struct multijmp_list *multijmp_list;
42 struct /* phi_node */ {
43 struct phi_list *phi_list;
45 struct /* unops */ {
46 struct symbol *orig_type; /* casts */
47 pseudo_t src;
49 struct /* binops */ {
50 pseudo_t src1, src2;
52 struct /* multijump */ {
53 int begin, end;
55 struct /* setval */ {
56 struct expression *val;
58 struct /* call */ {
59 pseudo_t func;
60 struct pseudo_list *arguments;
65 enum opcode {
66 OP_BADOP,
67 /* Terminator */
68 OP_TERMINATOR,
69 OP_RET = OP_TERMINATOR,
70 OP_BR,
71 OP_SWITCH,
72 OP_INVOKE,
73 OP_UNWIND,
74 OP_TERMINATOR_END = OP_UNWIND,
76 /* Binary */
77 OP_BINARY,
78 OP_ADD = OP_BINARY,
79 OP_SUB,
80 OP_MUL,
81 OP_DIV,
82 OP_MOD,
83 OP_SHL,
84 OP_SHR,
85 OP_BINARY_END = OP_SHR,
87 /* Logical */
88 OP_LOGICAL,
89 OP_AND = OP_LOGICAL,
90 OP_OR,
91 OP_XOR,
92 OP_LOGICAL_END = OP_XOR,
94 /* Binary comparison */
95 OP_BINCMP,
96 OP_SET_EQ = OP_BINCMP,
97 OP_SET_NE,
98 OP_SET_LE,
99 OP_SET_GE,
100 OP_SET_LT,
101 OP_SET_GT,
102 OP_BINCMP_END = OP_SET_GT,
104 /* Uni */
105 OP_NOT,
106 OP_NEG,
108 /* Memory */
109 OP_MALLOC,
110 OP_FREE,
111 OP_ALLOCA,
112 OP_LOAD,
113 OP_STORE,
114 OP_SETVAL,
115 OP_GET_ELEMENT_PTR,
117 /* Other */
118 OP_PHI,
119 OP_CAST,
120 OP_CALL,
121 OP_VANEXT,
122 OP_VAARG,
125 struct basic_block_list;
126 struct instruction_list;
129 * Basic block flags. Right now we only have one, which keeps
130 * track (at build time) whether the basic block has been branched
131 * out of yet.
133 #define BB_REACHABLE 0x00000001
135 struct basic_block {
136 unsigned long flags; /* BB status flags */
137 struct basic_block_list *parents; /* sources */
138 struct instruction_list *insns; /* Linear list of instructions */
141 static inline int is_branch_goto(struct instruction *br)
143 return br && br->opcode==OP_BR && (!br->bb_true || !br->bb_false);
146 static inline void add_bb(struct basic_block_list **list, struct basic_block *bb)
148 add_ptr_list((struct ptr_list **)list, bb);
151 static inline void add_instruction(struct instruction_list **list, struct instruction *insn)
153 add_ptr_list((struct ptr_list **)list, insn);
156 static inline void add_multijmp(struct multijmp_list **list, struct multijmp *multijmp)
158 add_ptr_list((struct ptr_list **)list, multijmp);
161 static inline void add_phi(struct phi_list **list, struct phi *phi)
163 add_ptr_list((struct ptr_list **)list, phi);
166 static inline void add_pseudo(struct pseudo_list **list, struct pseudo *pseudo)
168 add_ptr_list((struct ptr_list **)list, pseudo);
172 static inline int bb_terminated(struct basic_block *bb)
174 struct instruction *insn;
175 if (!bb)
176 return 0;
177 insn = last_instruction(bb->insns);
178 return insn && insn->opcode >= OP_RET && insn->opcode <= OP_UNWIND;
181 static inline int bb_reachable(struct basic_block *bb)
183 return bb && (bb->parents || (bb->flags & BB_REACHABLE));
186 struct entrypoint {
187 struct symbol *name;
188 struct symbol_list *syms;
189 struct basic_block_list *bbs;
190 struct basic_block *active;
193 void linearize_symbol(struct symbol *sym);
195 #endif /* LINEARIZE_H */