PIPS
instruction_selection.c
Go to the documentation of this file.
1 /*
2 
3  $Id: instruction_selection.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 
31 #include "genC.h"
32 #include "linear.h"
33 
34 #include "ri.h"
35 #include "effects.h"
36 
37 #include "misc.h"
38 #include "ri-util.h"
39 #include "effects-util.h"
40 #include "resources.h"
41 #include "pipsdbm.h"
42 
43 #define DEBUG_NAME "INSTRUCTION_SELECTION_DEBUG_LEVEL"
44 
45 typedef struct
46 {
47  /* input */
49 
50  /* output */
51  entity imaop, imsop;
52 
53  /* stats */
54  int n_ima, n_ims;
55 }
57 
58 /* whether e is a call to op with len parameters
59  * if ok, the list of arguments is returned.
60  * if not, NIL is returned.
61  */
62 static list /* of expression */
63 is_this_op(expression e, entity op, size_t len)
64 {
65  if (expression_call_p(e))
66  {
68  list args = call_arguments(c);
69  if (call_function(c)==op && gen_length(args)==len)
70  return args;
71  }
72  return NIL;
73 }
74 
75 static void update_call(call c, entity op, expression e, list le)
76 {
77  expression
78  a = EXPRESSION(gen_nth(0, le)),
79  b = EXPRESSION(gen_nth(1, le));
80 
81  /* ??? MEMORY LEAK */
82  call_function(c) = op;
84 }
85 
86 static void select_op_rwt(call c, inst_sel_ctx * ctx)
87 {
88  entity fun = call_function(c);
89  list /* of expression */ args = call_arguments(c);
90  int nargs = gen_length(args);
91 
92  if (fun==ctx->bplus && nargs==2)
93  {
94  list /* of expression */ lm;
95 
96  lm = is_this_op(EXPRESSION(gen_nth(0, args)), ctx->bmult, 2);
97  if (lm)
98  {
99  /* a * b + c -> ima(a,b,c) */
100  update_call(c, ctx->imaop, EXPRESSION(gen_nth(1, args)), lm);
101  ctx->n_ima++;
102  }
103  else
104  {
105  lm = is_this_op(EXPRESSION(gen_nth(1, args)), ctx->bmult, 2);
106  if (lm)
107  {
108  /* a + b * c -> ima(b,c,a) */
109  update_call(c, ctx->imaop, EXPRESSION(gen_nth(0, args)), lm);
110  ctx->n_ima++;
111  }
112  }
113  /* a * b + -c -> ims(a,b,c) */
114  /* -a + b * c -> ims(b,c,a) */
115  }
116  else if (fun==ctx->bminus && nargs==2)
117  {
118  list /* of expression */ lm;
119 
120  lm = is_this_op(EXPRESSION(gen_nth(0, args)), ctx->bmult, 2);
121  if (lm)
122  {
123  /* a * b - c -> ims(a,b,c) */
124  update_call(c, ctx->imsop, EXPRESSION(gen_nth(1, args)), lm);
125  ctx->n_ims++;
126  }
127  else
128  {
129  /* a - b * c -> -ims(b,c,a) */
130  /* -a - b * c -> -ima(b,c,a) */
131  /*
132  lm = is_this_op(EXPRESSION(gen_nth(1, args)), ctx->bmult, 2);
133  if (lm)
134  {
135  update_call(c, ctx->imaop, EXPRESSION(gen_nth(0, args)), lm);
136  ctx->n_ima++;
137  }
138  */
139  }
140  }
141  return;
142 }
143 
145 {
146  inst_sel_ctx ctx;
147  statement stat;
148 
150 
151  /* get data from pipsdbm
152  */
154 
156  db_get_memory_resource(DBR_CODE, module_name, true));
157 
159 
160  /* init gen_recurse context
161  */
168  ctx.n_ima = 0;
169  ctx.n_ims = 0;
170 
171  gen_context_multi_recurse(stat, &ctx,
173  /* Do not optimize subscript expressions */
175  NULL);
176 
177  /* store statement back to pipsdbm
178  */
179  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, stat);
180 
183 
184  debug_off();
185 
186  return true;
187 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
list gen_make_list(int domain,...)
Definition: list.c:851
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
bool instruction_selection(const char *module_name)
instruction_selection.c
static list is_this_op(expression e, entity op, size_t len)
whether e is a call to op with len parameters if ok, the list of arguments is returned.
static void update_call(call c, entity op, expression e, list le)
static void select_op_rwt(call c, inst_sel_ctx *ctx)
#define DEBUG_NAME
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
static entity uminus
Definition: optimize.c:447
static entity bplus
A + (–B) -> A - B FMA -> FMS.
Definition: optimize.c:446
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define IMS_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
#define IMA_OPERATOR_NAME
Integer Multiply Add and Sub, FC 27/10/2005 for FI.
#define MULTIPLY_OPERATOR_NAME
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_call_p(expression e)
Definition: expression.c:415
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define call_function(x)
Definition: ri.h:709
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
entity imaop
output