Mark an inline symbol accessed when taking its address.
[smatch.git] / linearize.h
blobada834ade0967e8a015edac73085f601cec7466d
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_COMPUTEDGOTO,
76 OP_UNWIND,
77 OP_TERMINATOR_END = OP_UNWIND,
79 /* Binary */
80 OP_BINARY,
81 OP_ADD = OP_BINARY,
82 OP_SUB,
83 OP_MUL,
84 OP_DIV,
85 OP_MOD,
86 OP_SHL,
87 OP_SHR,
88 OP_SEL,
90 /* Logical */
91 OP_AND,
92 OP_OR,
93 OP_XOR,
94 OP_AND_BOOL,
95 OP_OR_BOOL,
96 OP_BINARY_END = OP_OR_BOOL,
98 /* Binary comparison */
99 OP_BINCMP,
100 OP_SET_EQ = OP_BINCMP,
101 OP_SET_NE,
102 OP_SET_LE,
103 OP_SET_GE,
104 OP_SET_LT,
105 OP_SET_GT,
106 OP_SET_B,
107 OP_SET_A,
108 OP_SET_BE,
109 OP_SET_AE,
110 OP_BINCMP_END = OP_SET_AE,
112 /* Uni */
113 OP_NOT,
114 OP_NEG,
116 /* Setcc - always in combination with a select or conditional branch */
117 OP_SETCC,
119 /* Memory */
120 OP_MALLOC,
121 OP_FREE,
122 OP_ALLOCA,
123 OP_LOAD,
124 OP_STORE,
125 OP_SETVAL,
126 OP_GET_ELEMENT_PTR,
128 /* Other */
129 OP_PHI,
130 OP_CAST,
131 OP_CALL,
132 OP_VANEXT,
133 OP_VAARG,
136 struct basic_block_list;
137 struct instruction_list;
140 * Basic block flags. Right now we only have one, which keeps
141 * track (at build time) whether the basic block has been branched
142 * out of yet.
144 #define BB_REACHABLE 0x00000001
146 struct basic_block {
147 unsigned long flags; /* BB status flags */
148 struct basic_block_list *parents; /* sources */
149 struct instruction_list *insns; /* Linear list of instructions */
152 static inline int is_branch_goto(struct instruction *br)
154 return br && br->opcode==OP_BR && (!br->bb_true || !br->bb_false);
157 static inline void add_bb(struct basic_block_list **list, struct basic_block *bb)
159 add_ptr_list((struct ptr_list **)list, bb);
162 static inline void add_instruction(struct instruction_list **list, struct instruction *insn)
164 add_ptr_list((struct ptr_list **)list, insn);
167 static inline void add_multijmp(struct multijmp_list **list, struct multijmp *multijmp)
169 add_ptr_list((struct ptr_list **)list, multijmp);
172 static inline void add_phi(struct phi_list **list, struct phi *phi)
174 add_ptr_list((struct ptr_list **)list, phi);
177 static inline void add_pseudo(struct pseudo_list **list, struct pseudo *pseudo)
179 add_ptr_list((struct ptr_list **)list, pseudo);
183 static inline int bb_terminated(struct basic_block *bb)
185 struct instruction *insn;
186 if (!bb)
187 return 0;
188 insn = last_instruction(bb->insns);
189 return insn && insn->opcode >= OP_RET && insn->opcode <= OP_UNWIND;
192 static inline int bb_reachable(struct basic_block *bb)
194 return bb && (bb->parents || (bb->flags & BB_REACHABLE));
197 struct entrypoint {
198 struct symbol *name;
199 struct symbol_list *syms;
200 struct basic_block_list *bbs;
201 struct basic_block *active;
204 struct entrypoint *linearize_symbol(struct symbol *sym);
205 void show_entry(struct entrypoint *ep);
207 #endif /* LINEARIZE_H */