[PATCH] boolean in constant expressions done right
[smatch.git] / linearize.h
blobc0ed0f1c5d505d1a96c7bc12f307b2e14b3d1b55
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 extern struct pseudo void_pseudo;
18 #define VOID (&void_pseudo)
20 struct multijmp {
21 struct basic_block *target;
22 int begin, end;
25 struct phi {
26 struct basic_block *source;
27 pseudo_t pseudo;
30 struct instruction {
31 struct symbol *type;
32 int opcode;
33 union {
34 pseudo_t target;
35 pseudo_t cond; /* for branch and switch */
37 union {
38 struct /* branch */ {
39 struct basic_block *bb_true, *bb_false;
41 struct /* switch */ {
42 struct multijmp_list *multijmp_list;
44 struct /* phi_node */ {
45 struct phi_list *phi_list;
47 struct /* unops */ {
48 struct symbol *orig_type; /* casts */
49 pseudo_t src;
51 struct /* binops */ {
52 pseudo_t src1, src2;
54 struct /* multijump */ {
55 int begin, end;
57 struct /* setval */ {
58 struct expression *val;
60 struct /* call */ {
61 pseudo_t func;
62 struct pseudo_list *arguments;
67 enum opcode {
68 OP_BADOP,
69 /* Terminator */
70 OP_TERMINATOR,
71 OP_RET = OP_TERMINATOR,
72 OP_BR,
73 OP_SWITCH,
74 OP_INVOKE,
75 OP_UNWIND,
76 OP_TERMINATOR_END = OP_UNWIND,
78 /* Binary */
79 OP_BINARY,
80 OP_ADD = OP_BINARY,
81 OP_SUB,
82 OP_MUL,
83 OP_DIV,
84 OP_MOD,
85 OP_SHL,
86 OP_SHR,
87 OP_BINARY_END = OP_SHR,
89 /* Logical */
90 OP_LOGICAL,
91 OP_AND = OP_LOGICAL,
92 OP_OR,
93 OP_XOR,
94 OP_LOGICAL_END = OP_XOR,
96 /* Binary comparison */
97 OP_BINCMP,
98 OP_SET_EQ = OP_BINCMP,
99 OP_SET_NE,
100 OP_SET_LE,
101 OP_SET_GE,
102 OP_SET_LT,
103 OP_SET_GT,
104 OP_SET_B,
105 OP_SET_A,
106 OP_SET_BE,
107 OP_SET_AE,
108 OP_BINCMP_END = OP_SET_AE,
110 /* Uni */
111 OP_NOT,
112 OP_NEG,
114 /* Memory */
115 OP_MALLOC,
116 OP_FREE,
117 OP_ALLOCA,
118 OP_LOAD,
119 OP_STORE,
120 OP_SETVAL,
121 OP_GET_ELEMENT_PTR,
123 /* Other */
124 OP_PHI,
125 OP_CAST,
126 OP_CALL,
127 OP_VANEXT,
128 OP_VAARG,
131 struct basic_block_list;
132 struct instruction_list;
135 * Basic block flags. Right now we only have one, which keeps
136 * track (at build time) whether the basic block has been branched
137 * out of yet.
139 #define BB_REACHABLE 0x00000001
141 struct basic_block {
142 unsigned long flags; /* BB status flags */
143 struct basic_block_list *parents; /* sources */
144 struct instruction_list *insns; /* Linear list of instructions */
147 static inline int is_branch_goto(struct instruction *br)
149 return br && br->opcode==OP_BR && (!br->bb_true || !br->bb_false);
152 static inline void add_bb(struct basic_block_list **list, struct basic_block *bb)
154 add_ptr_list((struct ptr_list **)list, bb);
157 static inline void add_instruction(struct instruction_list **list, struct instruction *insn)
159 add_ptr_list((struct ptr_list **)list, insn);
162 static inline void add_multijmp(struct multijmp_list **list, struct multijmp *multijmp)
164 add_ptr_list((struct ptr_list **)list, multijmp);
167 static inline void add_phi(struct phi_list **list, struct phi *phi)
169 add_ptr_list((struct ptr_list **)list, phi);
172 static inline void add_pseudo(struct pseudo_list **list, struct pseudo *pseudo)
174 add_ptr_list((struct ptr_list **)list, pseudo);
178 static inline int bb_terminated(struct basic_block *bb)
180 struct instruction *insn;
181 if (!bb)
182 return 0;
183 insn = last_instruction(bb->insns);
184 return insn && insn->opcode >= OP_RET && insn->opcode <= OP_UNWIND;
187 static inline int bb_reachable(struct basic_block *bb)
189 return bb && (bb->parents || (bb->flags & BB_REACHABLE));
192 struct entrypoint {
193 struct symbol *name;
194 struct symbol_list *syms;
195 struct basic_block_list *bbs;
196 struct basic_block *active;
199 struct entrypoint *linearize_symbol(struct symbol *sym);
200 void show_entry(struct entrypoint *ep);
202 #endif /* LINEARIZE_H */