2 #include "for_normalize.h"
6 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*a))
11 static cmd_line_option my_options
[] = {
12 { CLO_MULTI_STRING
, "-func", "", &funcs
},
13 { CLO_NOARG
, "-verbose", "", &verbose
},
14 { CLO_NOARG
, "-oldstyle", "", &oldstyle
},
20 static void extract_context(tree_instr
*ti
, context_info
*ci
)
22 instruction
*in
= ti
->instr();
23 operand cpy
= in
->src_op(0);
24 assert(cpy
.is_expr());
25 operand op
= cpy
.instr()->src_op(0);
27 guard_constructor
gc(ci
->sa
, 1, NULL
);
28 assert(op
.kind() == OPER_INSTR
);
29 instruction
* ins
= op
.instr();
30 gc
.construct_guard(ins
);
32 ci
->ctx
= new SRelation(*gc
.s
, ci
->sa
);
35 static context_info
*handle_context(annote
*ca
, context_info
*ctx
)
37 immed_list
*ims
= ca
->immeds();
38 if (ims
->count() != 2)
40 immed val
= (*ims
)[1];
41 if (val
.kind() != im_symbol
)
43 sym_node
*sym
= val
.symbol();
44 if (sym
->kind() != SYM_PROC
)
47 assert(ctx
->ctx
== NULL
);
49 proc_sym
*proc
= static_cast<proc_sym
*>(sym
);
50 if (!proc
->is_in_memory())
52 ctx
->tp
= proc
->block();
53 tree_node_list
*tnl
= ctx
->tp
->body();
54 tree_node_list_iter
tnli(tnl
);
55 for (int i
= 0; !tnli
.is_empty(); ++i
) {
56 tree_node
*tn
= tnli
.step();
59 tree_instr
*in
= (tree_instr
*)tn
;
60 switch (in
->instr()->opcode()) {
62 extract_context(in
, ctx
);
80 static context_info
*handle_parameter(annote
*an
, context_info
*ctx
)
82 immed_list
*ims
= an
->immeds();
83 if (ims
->count() != 3 && ims
->count() != 4)
85 bool have_ub
= ims
->count() == 4;
86 immed val
= (*ims
)[1];
87 if (val
.kind() != im_symbol
)
89 sym_node
*sym
= val
.symbol();
90 if (sym
->kind() != SYM_VAR
)
93 if ((*ims
)[2].kind() != im_int
)
95 int lb
= (*ims
)[2].integer();
97 if (have_ub
&& (*ims
)[3].kind() != im_int
)
100 var_sym
* var
= static_cast<var_sym
*>(sym
);
101 ctx
->sa
->add_var(var
);
102 ctx
->sa
->vars
[var
]->lb
= lb
;
103 ctx
->sa
->vars
[var
]->lb_set
= true;
105 GEQ_Handle e1
= r
.and_with_GEQ();
106 e1
.update_coef(r
.get_local(ctx
->sa
->vars
[var
]), 1);
107 e1
.update_const(-lb
);
109 int ub
= (*ims
)[3].integer();
110 GEQ_Handle e2
= r
.and_with_GEQ();
111 e2
.update_coef(r
.get_local(ctx
->sa
->vars
[var
]), -1);
114 SRelation
*sr
= new SRelation(r
, ctx
->sa
);
118 SRelation
*r
= ctx
->ctx
;
119 ctx
->ctx
= r
->Intersection(sr
);
127 static context_info
*handle_pragmas(tree_proc
*tp
)
129 context_info
*ctx
= new context_info
;
130 const char *k_C_pragma
= lexicon
->enter("C pragma")->sp
;;
131 annote_list_iter
anli(tp
->proc()->file()->annotes());
132 while (!anli
.is_empty()) {
133 annote
*an
= anli
.step();
134 if (an
->name() != k_C_pragma
)
136 immed_list
*ims
= an
->immeds();
137 if (!(*ims
)[0].is_string())
139 if (strcmp((*ims
)[0].string(), "context") == 0)
140 ctx
= handle_context(an
, ctx
);
141 if (strcmp((*ims
)[0].string(), "parameter") == 0)
142 ctx
= handle_parameter(an
, ctx
);
147 /* Ensure for loops have step +1.
149 * We use a modified version of SUIF's normalize_fors_on_proc,
150 * since we don't mind that the lower bound may not be zero.
152 * The normalization will introduce an assignment to the old
153 * iterator. We have to propagate this assignment to all
154 * the accesses so that they no longer reference the old iterator.
155 * Afterward, this assignment needs to be removed, but we can't
156 * just use proc_dead_code since that will remove all dead code,
157 * including assignments to scalars in a program that we want
160 static void normalize_for_loops(tree_proc
*tp
)
162 instruction_list
*normalized
= normalized_fors_on_proc(tp
);
165 forward_propagate(tp
, FPK_ALL
);
166 fold_all_constants(tp
);
167 while (!normalized
->is_empty()) {
168 instruction
*ass
= normalized
->pop();
169 tree_instr
*parent
= ass
->parent();
170 parent
->parent()->remove(parent
->list_e());
171 delete parent
->list_e();
177 void do_proc(tree_proc
* tp
)
179 static context_info
*ctx
= NULL
;
182 ctx
= handle_pragmas(tp
);
185 proc_sym
* psym
= tp
->proc();
186 //printf("=======%s======= \n", psym->name());
187 for (f
= funcs
; **f
; ++f
)
188 if (!strcmp(*f
, psym
->name()))
190 if (f
!= funcs
&& **f
== '\0')
192 if (ctx
&& ctx
->tp
== tp
)
194 normalize_for_loops(tp
);
196 construct_domains(tp
, verbose
, oldstyle
, ctx
);
198 dump(tp
, ctx
, m_argc
, m_argv
);
201 int main(int argc
, char * argv
[])
204 m_argv
= new char* [argc
+1];
205 for (int i
= 0; i
< argc
; ++i
)
208 start_suif(argc
, argv
);
211 funcs
= new char *[argc
];
212 parse_cmd_line(argc
, argv
, my_options
, ARRAY_SIZE(my_options
));
214 suif_proc_iter(argc
, argv
, do_proc
, TRUE
);