benode.h 7.73 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Sebastian Hack's avatar
Sebastian Hack committed
6
/**
Christian Würdig's avatar
Christian Würdig committed
7
8
9
10
 * @file
 * @brief       Backend node support for generic backend nodes.
 * @author      Sebastian Hack
 * @date        17.05.2005
Sebastian Hack's avatar
Sebastian Hack committed
11
 *
Christian Würdig's avatar
Christian Würdig committed
12
 * Backend node support for generic backend nodes.
13
 * This file provides Perm, and Copy nodes.
Sebastian Hack's avatar
Sebastian Hack committed
14
 */
Christian Würdig's avatar
Christian Würdig committed
15
16
#ifndef FIRM_BE_BENODE_T_H
#define FIRM_BE_BENODE_T_H
17

18
19
#include <limits.h>

20
#include "firm_types.h"
21
#include "irnode_t.h"
Christian Würdig's avatar
Christian Würdig committed
22
#include "bearch.h"
Sebastian Hack's avatar
Sebastian Hack committed
23

24
25
typedef enum be_opcode {
	beo_Perm,
26
	beo_first = beo_Perm,
27
28
29
30
31
	beo_MemPerm,
	beo_Copy,
	beo_Keep,
	beo_CopyKeep,
	beo_IncSP,
32
	beo_last  = beo_IncSP
33
34
} be_opcode;

35
36
37
38
/**
 * The benode op's.  Must be available to register emitter function.
 */
extern ir_op *op_be_Perm;
Matthias Braun's avatar
Matthias Braun committed
39
extern ir_op *op_be_MemPerm;
40
41
extern ir_op *op_be_Copy;
extern ir_op *op_be_Keep;
Michael Beck's avatar
Michael Beck committed
42
extern ir_op *op_be_CopyKeep;
43
44
extern ir_op *op_be_IncSP;

45
46
47
/**
 * Determines if irn is a be_node.
 */
48
49
50
bool is_be_node(const ir_node *irn);

be_opcode get_be_irn_opcode(const ir_node *node);
51

52
53
54
/**
 * Create all BE specific opcodes.
 */
55
void be_init_op(void);
56

Matthias Braun's avatar
Matthias Braun committed
57
58
void be_finish_op(void);

59
60
61
/**
 * Position numbers for the be_Copy inputs.
 */
62
enum {
63
	n_be_Copy_op = 0
64
};
65
66
67
68

/**
 * Make a new Copy node.
 */
69
ir_node *be_new_Copy(ir_node *block, ir_node *in);
70
/** Returns the Copy Argument. */
71
72
ir_node *be_get_Copy_op(const ir_node *cpy);

73
74
75
/**
 * Make a new Perm node.
 */
76
ir_node *be_new_Perm(arch_register_class_t const *cls, ir_node *block, int n, ir_node *const *in);
77
78
79
80
81
82
83

/**
 * Reduce a Perm.
 * Basically, we provide a map to remap the Perm's arguments. If an entry in the
 * map is -1, the argument gets deleted.
 * This function takes care, that the register data and the input array reflects
 * the changes described by the map.
84
85
 * This is needed by the Perm optimization/movement in belower.c, see
 * push_through_perm().
86
 * @param perm     The perm node.
87
88
89
90
 * @param new_size The new number of arguments (must be smaller or equal to the
 *                 current one).
 * @param map      A map assigning each operand a new index (or -1 to indicate
 *                 deletion).
91
92
93
 */
void be_Perm_reduce(ir_node *perm, int new_size, int *map);

94
95
/**
 * Create a new MemPerm node.
96
97
98
 * A MemPerm node exchanges the values of memory locations. (Typically entities
 * used as spillslots). MemPerm nodes perform this operation without modifying
 * any register values.
99
 */
100
101
102
ir_node *be_new_MemPerm(ir_node *block, int n, ir_node *const *in);

ir_node *be_new_Keep(ir_node *block, int arity, ir_node *const *in);
Sebastian Hack's avatar
Sebastian Hack committed
103

104
105
void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls,
                      ir_node *node);
106

Sebastian Hack's avatar
Sebastian Hack committed
107
108
/**
 * Make a stack pointer increase/decrease node.
109
110
 * @param sp     The stack pointer register.
 * @param block  The block to insert the node into.
Sebastian Hack's avatar
Sebastian Hack committed
111
 * @param old_sp The node defining the former stack pointer.
112
113
114
115
 * @param offset amount the stack should expand (positive offset) or shrink
 *               (negative offset). Note that the offset is independent of the
 *               natural stack direction of the architecture but just specifies
 *               abstract expanding/shrinking of the stack area.
116
117
 * @param align  force stack alignment to this power of 2. (i.e. specifying 4
 *               results in a 2**4 = 16 bytes stack alignment)
Sebastian Hack's avatar
Sebastian Hack committed
118
 * @return       A new stack pointer increment/decrement node.
119
120
 * @note         This node sets a register constraint to the @p sp register on
 *               its output.
Sebastian Hack's avatar
Sebastian Hack committed
121
 */
122
ir_node *be_new_IncSP(const arch_register_t *sp, ir_node *block,
123
                      ir_node *old_sp, int offset, unsigned align);
Sebastian Hack's avatar
Sebastian Hack committed
124

Michael Beck's avatar
BugFix:    
Michael Beck committed
125
126
/** Returns the previous node that computes the stack pointer. */
ir_node *be_get_IncSP_pred(ir_node *incsp);
Sebastian Hack's avatar
Sebastian Hack committed
127

128
/** Sets the previous node that computes the stack pointer. */
129
void     be_set_IncSP_pred(ir_node *incsp, ir_node *pred);
130

131
132
133
134
135
136
137
/**
 * Sets a new offset to a IncSP node.
 * A positive offset means expanding the stack, a negative offset shrinking
 * an offset is == BE_STACK_FRAME_SIZE will be replaced by the real size of the
 * stackframe in the fix_stack_offsets phase.
 */
void     be_set_IncSP_offset(ir_node *irn, int offset);
Michael Beck's avatar
BugFix:    
Michael Beck committed
138
139

/** Gets the offset from a IncSP node. */
140
int be_get_IncSP_offset(const ir_node *irn);
141
142
143
/** Return requested stack alignment (as a logarithm of two, i.e. 4 means
 * the stack alignment will be 2**4=16 bytes) */
unsigned be_get_IncSP_align(const ir_node *irn);
Sebastian Hack's avatar
Sebastian Hack committed
144

Sebastian Hack's avatar
Sebastian Hack committed
145
enum {
Matthias Braun's avatar
Matthias Braun committed
146
147
	n_be_CopyKeep_op,
	n_be_CopyKeep_max = n_be_CopyKeep_op
Sebastian Hack's avatar
Sebastian Hack committed
148
};
149
ir_node *be_new_CopyKeep(ir_node *block, ir_node *src, int n, ir_node *const *in_keep);
150

151
ir_node *be_new_CopyKeep_single(ir_node *block, ir_node *src, ir_node *keep);
152

153
ir_node *be_get_CopyKeep_op(const ir_node *cpy);
Sebastian Hack's avatar
Sebastian Hack committed
154

155
void be_set_CopyKeep_op(ir_node *cpy, ir_node *op);
Sebastian Hack's avatar
Sebastian Hack committed
156

157
158
void be_set_MemPerm_in_entity(const ir_node *irn, unsigned n, ir_entity* ent);
ir_entity *be_get_MemPerm_in_entity(const ir_node *irn, unsigned n);
Matthias Braun's avatar
Matthias Braun committed
159

160
161
void be_set_MemPerm_out_entity(const ir_node *irn, unsigned n, ir_entity* ent);
ir_entity *be_get_MemPerm_out_entity(const ir_node *irn, unsigned n);
162

163
164
165
void be_set_MemPerm_offset(ir_node *irn, int offset);
int be_get_MemPerm_offset(const ir_node *irn);

166
unsigned be_get_MemPerm_entity_arity(const ir_node *irn);
167

Sebastian Hack's avatar
Sebastian Hack committed
168
169
170
/**
 * Impose a register constraint on a backend node.
 * @param irn The node.
171
 * @param pos The position of the argument.
172
173
 * @param reg The register which is admissible for that node, argument/result
 *            and position.
Sebastian Hack's avatar
Sebastian Hack committed
174
 */
175
176
177
178
void be_set_constr_single_reg_in(ir_node *irn, int pos,
		const arch_register_t *reg, arch_register_req_type_t additional_flags);
void be_set_constr_single_reg_out(ir_node *irn, int pos,
		const arch_register_t *reg, arch_register_req_type_t additional_flags);
179

180
181
182
const arch_register_req_t *be_create_reg_req(struct obstack *obst,
		const arch_register_t *reg, arch_register_req_type_t additional_types);

183
/**
184
 * Impose register constraints on a backend node.
185
186
187
 * The register subsets given by the limited function in @p req are copied to
 * the backend node. This requires that the constraint type of the @p req is
 * arch_register_req_type_limited.
188
189
190
 * @param irn The backend node.
 * @param pos The position (@see be_set_constr_single_reg()).
 * @param req The register requirements which shall be transferred.
191
 */
192
void be_set_constr_out(ir_node *irn, int pos, const arch_register_req_t *req);
193

Sebastian Hack's avatar
Sebastian Hack committed
194
195
196
/**
 * Set the register class of a node.
 * @param irn The node itself.
197
 * @param pos The position (0..n) for arguments
Sebastian Hack's avatar
Sebastian Hack committed
198
199
 * @param flags The register class to set for that node and position.
 */
200
201
202
203
void be_node_set_reg_class_in(ir_node *irn, int pos,
                              const arch_register_class_t *cls);
void be_node_set_reg_class_out(ir_node *irn, int pos,
                               const arch_register_class_t *cls);
Sebastian Hack's avatar
Sebastian Hack committed
204

205
206
207
/**
 * Set the register requirements for a phi node.
 */
208
209
void be_set_phi_reg_req(ir_node *phi, const arch_register_req_t *req);

210
void be_dump_phi_reg_reqs(FILE *out, const ir_node *node, dump_reason_t reason);
211

212
213
214
215
/**
 * Creates a new phi with associated backend informations
 */
ir_node *be_new_Phi(ir_node *block, int n_ins, ir_node **ins, ir_mode *mode,
216
                    const arch_register_req_t *req);
217

218
219
220
221
222
/**
 * Search for output of start node with a specific register
 */
ir_node *be_get_initial_reg_value(ir_graph *irg, const arch_register_t *reg);

223
224
225
226
227
228
static inline bool be_is_Copy     (const ir_node *irn) { return get_irn_op(irn) == op_be_Copy     ; }
static inline bool be_is_CopyKeep (const ir_node *irn) { return get_irn_op(irn) == op_be_CopyKeep ; }
static inline bool be_is_Perm     (const ir_node *irn) { return get_irn_op(irn) == op_be_Perm     ; }
static inline bool be_is_MemPerm  (const ir_node *irn) { return get_irn_op(irn) == op_be_MemPerm  ; }
static inline bool be_is_Keep     (const ir_node *irn) { return get_irn_op(irn) == op_be_Keep     ; }
static inline bool be_is_IncSP    (const ir_node *irn) { return get_irn_op(irn) == op_be_IncSP    ; }
229

230
#endif