PandA-2024.02
parm_decl_taken_address_fix.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
41 #include "Parameter.hpp"
42 #include "application_manager.hpp"
43 #include "behavioral_helper.hpp"
44 #include "call_graph_manager.hpp"
45 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
46 #include "function_behavior.hpp"
47 #include "string_manipulation.hpp" // for GET_CLASS
48 #include "tree_basic_block.hpp"
49 #include "tree_helper.hpp"
50 #include "tree_manager.hpp"
51 #include "tree_manipulation.hpp"
52 #include "tree_node.hpp"
53 #include "tree_reindex.hpp"
54 
56  const application_managerRef AM, unsigned int fun_id,
57  const DesignFlowManagerConstRef dfm)
58  : FunctionFrontendFlowStep(AM, fun_id, PARM_DECL_TAKEN_ADDRESS, dfm, params)
59 {
60  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
61 }
62 
64 
67  const DesignFlowStep::RelationshipType relationship_type) const
68 {
70  switch(relationship_type)
71  {
73  {
74  relationships.insert(std::make_pair(CHECK_SYSTEM_TYPE, SAME_FUNCTION));
75  relationships.insert(std::make_pair(FIX_STRUCTS_PASSED_BY_VALUE, SAME_FUNCTION));
76  relationships.insert(std::make_pair(FUNCTION_CALL_TYPE_CLEANUP, SAME_FUNCTION));
77  relationships.insert(std::make_pair(IR_LOWERING, SAME_FUNCTION));
78  relationships.insert(std::make_pair(COMPUTE_IMPLICIT_CALLS, SAME_FUNCTION));
79  break;
80  }
82  {
83  break;
84  }
86  {
87  break;
88  }
89  default:
90  {
92  }
93  }
94  return relationships;
95 }
96 
98 {
99  bool changed = false;
100  const auto TM = AppM->get_tree_manager();
101  const auto IRman = tree_manipulationRef(new tree_manipulation(TM, parameters, AppM));
102  const auto tn = TM->GetTreeNode(function_id);
103  auto* fd = GetPointer<function_decl>(tn);
104  THROW_ASSERT(fd && fd->body, "Node " + STR(tn) + "is not a function_decl or has no body");
105  const auto* sl = GetPointer<const statement_list>(GET_NODE(fd->body));
106  THROW_ASSERT(sl, "Body is not a statement_list");
107  const std::string fu_name = tree_helper::name_function(TM, function_id);
108  THROW_ASSERT(!GetPointer<const function_type>(GET_CONST_NODE(tree_helper::CGetType(tn)))->varargs_flag,
109  "function " + fu_name + " is varargs");
110  // compute the set of parm_decl for which an address is taken
111  CustomOrderedSet<unsigned int> parm_decl_addr;
112  std::map<unsigned int, tree_nodeRef> parm_decl_var_decl_rel;
113  for(auto& block : sl->list_of_bloc)
114  {
115  for(const auto& stmt : block.second->CGetStmtList())
116  {
117  if(GET_NODE(stmt)->get_kind() == gimple_assign_K)
118  {
119  const auto* ga = GetPointer<const gimple_assign>(GET_NODE(stmt));
120  if(GET_NODE(ga->op1)->get_kind() == addr_expr_K)
121  {
122  auto* ae = GetPointer<addr_expr>(GET_NODE(ga->op1));
123  if(GET_NODE(ae->op)->get_kind() == parm_decl_K)
124  {
125  parm_decl_addr.insert(GET_INDEX_NODE(ae->op));
126  }
127  }
128  }
129  }
130  }
131  for(auto par_index : parm_decl_addr)
132  {
133  auto par = TM->CGetTreeReindex(par_index);
134  const auto* pd = GetPointer<const parm_decl>(GET_NODE(par));
135  THROW_ASSERT(pd, "unexpected condition");
136  const auto& p_type = pd->type;
137  const std::string srcp = pd->include_name + ":" + STR(pd->line_number) + ":" + STR(pd->column_number);
138  const auto original_param_name =
139  pd->name ? GetPointer<const identifier_node>(GET_NODE(pd->name))->strg : STR(par_index);
140  const std::string local_var_name = "bambu_artificial_local_parameter_copy_" + original_param_name;
141  const auto local_var_identifier = IRman->create_identifier_node(local_var_name);
142  const auto new_local_var_decl =
143  IRman->create_var_decl(local_var_identifier, p_type, pd->scpe, pd->size, tree_nodeRef(), tree_nodeRef(), srcp,
144  GetPointer<const type_node>(GET_NODE(p_type))->algn, pd->used);
145  parm_decl_var_decl_rel[par_index] = new_local_var_decl;
146 
147  for(auto& block : sl->list_of_bloc)
148  {
149  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Examining BB" + STR(block.first));
150  for(const auto& stmt : block.second->CGetStmtList())
151  {
153  "-->Examining statement " + GET_NODE(stmt)->ToString());
154  TM->ReplaceTreeNode(stmt, par, new_local_var_decl);
156  "<--Examined statement " + GET_NODE(stmt)->ToString());
157  }
158  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Examined BB" + STR(block.first));
159  }
160  }
161  if(!parm_decl_addr.empty())
162  {
164  const auto entry_block = sl->list_of_bloc.at(BB_ENTRY);
165  const auto succ_blocks = entry_block->list_of_succ;
166  THROW_ASSERT(succ_blocks.size() == 1,
167  "entry basic block of function " + fu_name + " has " + STR(succ_blocks.size()) + " successors");
168  auto bb_index = *succ_blocks.begin();
169  const auto first_block = sl->list_of_bloc.at(bb_index);
170  for(auto par_index : parm_decl_addr)
171  {
172  auto par = TM->CGetTreeReindex(par_index);
173  auto vd = parm_decl_var_decl_rel.at(par_index);
174  const auto* pd = GetPointer<const parm_decl>(GET_NODE(par));
175  THROW_ASSERT(pd, "unexpected condition");
176  const std::string srcp_default = pd->include_name + ":" + STR(pd->line_number) + ":" + STR(pd->column_number);
177  auto new_ga_expr = IRman->CreateGimpleAssignAddrExpr(GET_NODE(vd), function_id, srcp_default);
178  first_block->PushFront(new_ga_expr, AppM);
180  "---New statement statement " + GET_NODE(new_ga_expr)->ToString());
181  auto* nge = GetPointer<gimple_assign>(GET_NODE(new_ga_expr));
182  nge->temporary_address = true;
183  tree_nodeRef ssa_addr = nge->op0;
184  auto* sa = GetPointer<ssa_name>(GET_NODE(ssa_addr));
185  tree_nodeRef offset = TM->CreateUniqueIntegerCst(0, sa->type);
186 
187  const tree_nodeRef p_type = pd->type;
188  auto mr = IRman->create_binary_operation(p_type, ssa_addr, offset, srcp_default, mem_ref_K);
189  tree_nodeRef ssa_par = IRman->create_ssa_name(par, p_type, tree_nodeRef(), tree_nodeRef());
190  tree_nodeRef ga = IRman->create_gimple_modify_stmt(mr, ssa_par, function_id, srcp_default);
191  first_block->PushAfter(ga, new_ga_expr, AppM);
192  GetPointer<gimple_node>(GET_NODE(ga))->artificial = true;
194  "---New statement statement " + GET_NODE(ga)->ToString());
195  }
196  changed = true;
197  }
198 
199  if(changed)
200  {
201  function_behavior->UpdateBBVersion();
203  }
205 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
static std::string name_function(const tree_managerConstRef &tm, const unsigned int index)
Return the name of the function.
File containing functions and utilities to support the printing of debug messagges.
Step successfully executed.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
parm_decl_taken_address_fix(const ParameterConstRef params, const application_managerRef AM, unsigned int fun_id, const DesignFlowManagerConstRef dfm)
Constructor.
struct definition of the source position.
Definition: tree_node.hpp:832
RelationshipType
The relationship type.
Source must be executed to satisfy target.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:361
Data structure describing a basic block at tree level.
std::string include_name
include_name is a filename string, this can be the location of a reference, if no definition has been...
Definition: tree_node.hpp:839
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
#define BB_ENTRY
constant identifying the basic block node of type entry
unsigned offset[NUM_VERTICES+1]
Definition: graph.h:3
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
This struct specifies the block node.
Definition: tree_node.hpp:1820
This file collects some utility functions.
const unsigned int function_id
The index of the function to be analyzed.
~parm_decl_taken_address_fix() override
Destructor.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
this class is used to manage the command-line or XML options.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
Wrapper to call graph.
int debug_level
The debug level.
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
int sl
Definition: adpcm.c:105
DesignFlowStep_Status InternalExec() override
Execute the step.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:52 for PandA-2024.02 by doxygen 1.8.13