15 struct instruction
*insn
;
19 DECLARE_ALLOCATOR(pseudo_user
);
20 DECLARE_PTR_LIST(pseudo_user_list
, struct pseudo_user
);
21 DECLARE_PTRMAP(phi_map
, struct symbol
*, struct instruction
*);
36 enum pseudo_type type
;
37 struct pseudo_user_list
*users
;
41 struct instruction
*def
;
47 extern struct pseudo void_pseudo
;
49 #define VOID (&void_pseudo)
51 static inline bool is_zero(pseudo_t pseudo
)
53 return pseudo
->type
== PSEUDO_VAL
&& pseudo
->value
== 0;
56 static inline bool is_nonzero(pseudo_t pseudo
)
58 return pseudo
->type
== PSEUDO_VAL
&& pseudo
->value
!= 0;
61 static inline bool is_positive(pseudo_t pseudo
, unsigned size
)
63 return pseudo
->type
== PSEUDO_VAL
&& !(pseudo
->value
& sign_bit(size
));
68 struct basic_block
*target
;
72 struct asm_constraint
{
74 const char *constraint
;
75 const struct ident
*ident
;
76 unsigned int is_memory
:1;
79 DECLARE_ALLOCATOR(asm_constraint
);
80 DECLARE_PTR_LIST(asm_constraint_list
, struct asm_constraint
);
83 struct asm_constraint_list
*inputs
;
84 struct asm_constraint_list
*outputs
;
85 struct asm_constraint_list
*clobbers
;
88 DECLARE_ALLOCATOR(asm_rules
);
94 struct basic_block
*bb
;
99 struct /* entrypoint */ {
100 struct pseudo_list
*arg_list
;
102 struct /* branch */ {
104 struct basic_block
*bb_true
, *bb_false
;
106 struct /* switch */ {
108 struct multijmp_list
*multijmp_list
;
110 struct /* phi_node */ {
111 pseudo_t phi_var
; // used for SSA conversion
112 struct pseudo_list
*phi_list
;
115 struct /* phi source */ {
117 struct instruction
*phi_node
;
121 unsigned from
; /* slice */
122 struct symbol
*orig_type
; /* casts */
124 struct /* memops */ {
125 pseudo_t addr
; /* alias .src */
127 unsigned int is_volatile
:1;
129 struct /* binops and sel */ {
130 pseudo_t src1
, src2
, src3
;
132 struct /* compare */ {
133 pseudo_t _src1
, _src2
; // alias .src[12]
134 struct symbol
*itype
; // input operands' type
136 struct /* setval */ {
137 struct expression
*val
;
139 struct /* setfval */ {
144 struct pseudo_list
*arguments
;
145 struct symbol_list
*fntypes
;
147 struct /* context */ {
150 struct expression
*context_expr
;
154 struct asm_rules
*asm_rules
;
155 unsigned int clobber_memory
:1;
156 unsigned int output_memory
:1;
161 struct basic_block_list
;
162 struct instruction_list
;
166 unsigned long generation
;
167 struct entrypoint
*ep
;
168 struct basic_block_list
*parents
; /* sources */
169 struct basic_block_list
*children
; /* destinations */
170 struct instruction_list
*insns
; /* Linear list of instructions */
171 struct basic_block
*idom
; /* link to the immediate dominator */
172 unsigned int nr
; /* unique id for label's names */
173 int dom_level
; /* level in the dominance tree */
174 struct basic_block_list
*doms
; /* list of BB idominated by this one */
175 struct pseudo_list
*needs
, *defines
;
177 struct phi_map
*phi_map
;/* needed during SSA conversion */
178 int postorder_nr
; /* postorder number */
179 int context
; /* needed during context checking */
186 // return the opcode of the instruction defining ``SRC`` if existing
187 // and OP_BADOP if not. It also assigns the defining instruction
189 #define DEF_OPCODE(DEF, SRC) \
190 (((SRC)->type == PSEUDO_REG && (DEF = (SRC)->def)) ? DEF->opcode : OP_BADOP)
193 static inline void add_bb(struct basic_block_list
**list
, struct basic_block
*bb
)
195 add_ptr_list(list
, bb
);
198 static inline void add_instruction(struct instruction_list
**list
, struct instruction
*insn
)
200 add_ptr_list(list
, insn
);
203 static inline void insert_last_instruction(struct basic_block
*bb
, struct instruction
*insn
)
205 struct instruction
*last
= delete_last_instruction(&bb
->insns
);
206 add_instruction(&bb
->insns
, insn
);
207 add_instruction(&bb
->insns
, last
);
211 static inline void add_multijmp(struct multijmp_list
**list
, struct multijmp
*multijmp
)
213 add_ptr_list(list
, multijmp
);
216 static inline pseudo_t
*add_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
218 return add_ptr_list(list
, pseudo
);
221 static inline int remove_pseudo(struct pseudo_list
**list
, pseudo_t pseudo
)
223 return delete_ptr_list_entry((struct ptr_list
**)list
, pseudo
, 0) != 0;
226 static inline int pseudo_in_list(struct pseudo_list
*list
, pseudo_t pseudo
)
228 return lookup_ptr_list_entry((struct ptr_list
*)list
, pseudo
);
231 static inline int bb_terminated(struct basic_block
*bb
)
233 struct instruction
*insn
;
236 insn
= last_instruction(bb
->insns
);
237 return insn
&& insn
->opcode
>= OP_TERMINATOR
238 && insn
->opcode
<= OP_TERMINATOR_END
;
241 static inline int bb_reachable(struct basic_block
*bb
)
246 static inline int lookup_bb(struct basic_block_list
*list
, struct basic_block
*bb
)
248 return lookup_ptr_list_entry((struct ptr_list
*)list
, bb
);
252 static inline void add_pseudo_user_ptr(struct pseudo_user
*user
, struct pseudo_user_list
**list
)
254 add_ptr_list(list
, user
);
257 static inline int has_use_list(pseudo_t p
)
259 return (p
&& p
->type
!= PSEUDO_VOID
&& p
->type
!= PSEUDO_UNDEF
&& p
->type
!= PSEUDO_VAL
);
262 static inline bool has_definition(pseudo_t p
)
264 return p
->type
== PSEUDO_REG
|| p
->type
== PSEUDO_PHI
;
267 static inline int pseudo_user_list_size(struct pseudo_user_list
*list
)
269 return ptr_list_size((struct ptr_list
*)list
);
272 static inline bool pseudo_user_list_empty(struct pseudo_user_list
*list
)
274 return ptr_list_empty((struct ptr_list
*)list
);
277 static inline int has_users(pseudo_t p
)
279 return !pseudo_user_list_empty(p
->users
);
282 static inline bool one_use(pseudo_t p
)
284 return !ptr_list_multiple((struct ptr_list
*)(p
->users
));
287 static inline int nbr_users(pseudo_t p
)
289 return pseudo_user_list_size(p
->users
);
292 static inline struct pseudo_user
*alloc_pseudo_user(struct instruction
*insn
, pseudo_t
*pp
)
294 struct pseudo_user
*user
= __alloc_pseudo_user(0);
300 static inline void use_pseudo(struct instruction
*insn
, pseudo_t p
, pseudo_t
*pp
)
304 add_pseudo_user_ptr(alloc_pseudo_user(insn
, pp
), &p
->users
);
307 static inline void link_phi(struct instruction
*node
, pseudo_t phi
)
309 use_pseudo(node
, phi
, add_pseudo(&node
->phi_list
, phi
));
310 phi
->def
->phi_node
= node
;
313 static inline void remove_bb_from_list(struct basic_block_list
**list
, struct basic_block
*entry
, int count
)
315 delete_ptr_list_entry((struct ptr_list
**)list
, entry
, count
);
318 static inline void replace_bb_in_list(struct basic_block_list
**list
,
319 struct basic_block
*old
, struct basic_block
*new, int count
)
321 replace_ptr_list_entry((struct ptr_list
**)list
, old
, new, count
);
326 struct symbol_list
*syms
;
327 struct pseudo_list
*accesses
;
328 struct basic_block_list
*bbs
;
329 struct basic_block
*active
;
330 struct instruction
*entry
;
331 unsigned int dom_levels
; /* max levels in the dom tree */
334 extern void insert_select(struct basic_block
*bb
, struct instruction
*br
, struct instruction
*phi
, pseudo_t if_true
, pseudo_t if_false
);
336 struct instruction
*alloc_phisrc(pseudo_t pseudo
, struct symbol
*type
);
337 struct instruction
*alloc_phi_node(struct basic_block
*bb
, struct symbol
*type
, struct ident
*ident
);
338 struct instruction
*insert_phi_node(struct basic_block
*bb
, struct symbol
*var
);
339 void add_phi_node(struct basic_block
*bb
, struct instruction
*phi_node
);
341 pseudo_t
alloc_phi(struct basic_block
*source
, pseudo_t pseudo
, struct symbol
*type
);
342 pseudo_t
alloc_pseudo(struct instruction
*def
);
343 pseudo_t
value_pseudo(long long val
);
344 pseudo_t
undef_pseudo(void);
346 struct entrypoint
*linearize_symbol(struct symbol
*sym
);
347 int unssa(struct entrypoint
*ep
);
348 void show_entry(struct entrypoint
*ep
);
349 void show_insn_entry(struct instruction
*insn
);
350 const char *show_pseudo(pseudo_t pseudo
);
351 void show_bb(struct basic_block
*bb
);
352 void show_insn_bb(struct instruction
*insn
);
353 const char *show_instruction(struct instruction
*insn
);
354 const char *show_label(struct basic_block
*bb
);
356 #endif /* LINEARIZE_H */