PIPS
allocatable.c
Go to the documentation of this file.
1 /*
2 
3  $Id: allocatable.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6  Copyright 2009-2010 HPC Project
7 
8  This file is part of PIPS.
9 
10  PIPS is free software: you can redistribute it and/or modify it
11  under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  any later version.
14 
15  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
16  WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  FITNESS FOR A PARTICULAR PURPOSE.
18 
19  See the GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
23 
24  */
25 #ifdef HAVE_CONFIG_H
26 #include "pips_config.h"
27 #endif
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "genC.h"
34 #include "linear.h"
35 #include "misc.h"
36 #include "ri.h"
37 
38 #include "ri-util.h"
39 
40 /***
41  * Handling of ALLOCATABLE (Fortran95)
42  *
43  * Allocatable are represented internally as structure, for instance :
44  *
45  * integer, dimension (:,:,:), allocatable :: myarray
46  *
47  * would be represented as (pseudo code display here) :
48  *
49  * struct __pips_allocatable__2D myarray;
50  *
51  * with
52  *
53  * struct __pips_allocatable__2D {
54  * int lowerbound1;
55  * int upperbound1;
56  * int lowerbound2;
57  * int upperbound2;
58  * int data[lowerbound1:upperbound1][lowerbound2:upperbound2]
59  * }
60  *
61  * The structure is dependent of the number of dimension and is created
62  * dynamically when encounting an allocatable declaration.
63  *
64  * The prettyprint recognize the structure based on the special prefix and
65  * display it as an allocatable array in Fortran95.
66  *
67  */
68 
69 /**
70  * @brief Check if an entity is an allocatable
71  */
73  type t = entity_type(e);
74  if(!type_variable_p(t)) {
75  return false;
76  }
77  variable v = type_variable(t);
79  return false;
80  }
81  entity allocatable_struct = basic_derived(variable_basic(v));
82 
83  if(!same_stringn_p(entity_local_name(allocatable_struct),
85  sizeof(STRUCT_PREFIX ALLOCATABLE_PREFIX)-1)) {
86  return false;
87  }
88 
89  return true;
90 }
91 
92 /**
93  * @brief Check if an expression is a reference to an allocatable array
94  */
96  // This must be a call
97  if(!expression_call_p(e)) {
98  return false;
99  }
100 
101  entity field_call = call_function(expression_call(e));
102  list args_list = call_arguments(expression_call(e));
103 
104  // This must be a call to "." and we must have args
105  if(!ENTITY_FIELD_P(field_call) || ENDP(args_list)) {
106  return false;
107  }
108 
109  // Check that we deal with an allocatable
110  expression allocatable_exp = CAR(args_list).e;
111  entity allocatable =
112  reference_variable(expression_reference(allocatable_exp));
113  if(!entity_allocatable_p(allocatable)) {
114  return false;
115  } else {
116  pips_assert("Allocatable shouldn't have any indices !",
117  ENDP(reference_indices(expression_reference(allocatable_exp))));
118  }
119 
120  // Check that it is the data field
121  expression field_exp = CAR(CDR(args_list)).e;
122  pips_assert("Allocatable field shouldn't have any indices !",
124  entity field = reference_variable(expression_reference(field_exp));
130  strlen(ALLOCATABLE_UBOUND_PREFIX))) {
131  return false;
132  }
133 
134  return true;
135 }
136 
137 /**
138  * @brief This function produce an expression that is an access to the array
139  * inside the allocatable structure.
140  */
142  pips_assert("Entity isn't an allocatable", entity_allocatable_p(e));
143 
144  entity data_field = get_allocatable_data_entity(e);
145 
146  // Construct the expression e.data
149  entity_to_expression(data_field));
150 
151 }
152 
153 /**
154  * @brief Get the entity inside the struct corresponding to the array,
155  * mostly for correct prettyprint
156  */
158  pips_assert("Entity isn't an allocatable", entity_allocatable_p(e));
159 
160  // Get the data field inside the allocatable struct
162  entity allocatable_struct = basic_derived(variable_basic(v));
163  entity data_field = CAR(type_struct(entity_type(allocatable_struct))).e;
164  return data_field;
165 }
166 
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define same_stringn_p(a, b, c)
Definition: misc-local.h:199
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define STRUCT_PREFIX
Definition: naming-local.h:56
#define ALLOCATABLE_UBOUND_PREFIX
#define FIELD_OPERATOR_NAME
Definition: ri-util-local.h:91
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
#define ALLOCATABLE_PREFIX
#define ALLOCATABLE_LBOUND_PREFIX
expression get_allocatable_data_expr(entity e)
This function produce an expression that is an access to the array inside the allocatable structure.
Definition: allocatable.c:141
bool entity_allocatable_p(entity e)
Check if an entity is an allocatable.
Definition: allocatable.c:72
bool expression_allocatable_data_access_p(expression e)
Check if an expression is a reference to an allocatable array.
Definition: allocatable.c:95
entity get_allocatable_data_entity(entity e)
Get the entity inside the struct corresponding to the array, mostly for correct prettyprint.
Definition: allocatable.c:157
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
bool expression_call_p(expression e)
Definition: expression.c:415
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
call expression_call(expression e)
Definition: expression.c:445
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
#define type_struct(x)
Definition: ri.h:2964
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define basic_derived(x)
Definition: ri.h:640
#define type_variable(x)
Definition: ri.h:2949
#define basic_derived_p(x)
Definition: ri.h:638
#define reference_indices(x)
Definition: ri.h:2328
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
The structure used to build lists in NewGen.
Definition: newgen_list.h:41