PandA-2024.02
OrderedInstructions.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) 2023-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  */
43 #include "OrderedInstructions.hpp"
44 
45 #include "Dominance.hpp"
46 #include "basic_block.hpp"
47 #include "exceptions.hpp"
48 #include "tree_basic_block.hpp"
49 #include "tree_node.hpp"
50 #include "tree_reindex.hpp"
51 
52 bool OrderedBasicBlock::instComesBefore(const struct gimple_node* A, const struct gimple_node* B)
53 {
54  const struct gimple_node* Inst = nullptr;
55  THROW_ASSERT(!(LastInstFound == BBInst.end() && NextInstPos != 0), "Instruction supposed to be in NumberedInsts");
56 
57  // Start the search with the instruction found in the last lookup round.
58  auto II = BBInst.begin();
59  auto IE = BBInst.end();
60  if(LastInstFound != IE)
61  {
62  II = std::next(LastInstFound);
63  }
64 
65  // Number all instructions up to the point where we find 'A' or 'B'.
66  for(; II != IE; ++II)
67  {
68  Inst = GetPointer<const gimple_node>(GET_CONST_NODE(*II));
69  NumberedInsts[Inst] = NextInstPos++;
70  if(Inst == A || Inst == B)
71  {
72  break;
73  }
74  }
75 
76  THROW_ASSERT(II != IE, "Instruction not found?");
77  THROW_ASSERT((Inst == A || Inst == B), "Should find A or B");
78  LastInstFound = II;
79  return Inst != B;
80 }
81 
83  : LastInstFound(BasicB->CGetStmtList().end()), NextInstPos(0), BBInst(BasicB->CGetStmtList()), BB(BasicB)
84 {
85  unsigned int phiPos = 0U;
86  for(const auto& gp : BasicB->CGetPhiList())
87  {
88  NumberedInsts.insert({GetPointer<const gimple_node>(GET_CONST_NODE(gp)), phiPos++});
89  }
90 }
91 
92 bool OrderedBasicBlock::dominates(const struct gimple_node* A, const struct gimple_node* B)
93 {
94  THROW_ASSERT(A->bb_index == B->bb_index, "Instructions must be in the same basic block!");
95  THROW_ASSERT(A->bb_index == BB->number, "Instructions must be in the tracked block!");
96 
97  // Phi statements always comes before non-phi statements
98  if(A->get_kind() == gimple_phi_K && B->get_kind() != gimple_phi_K)
99  {
100  return true;
101  }
102  else if(A->get_kind() != gimple_phi_K && B->get_kind() == gimple_phi_K)
103  {
104  return false;
105  }
106 
107  // First we lookup the instructions. If they don't exist, lookup will give us
108  // back ::end(). If they both exist, we compare the numbers. Otherwise, if NA
109  // exists and NB doesn't, it means NA must come before NB because we would
110  // have numbered NB as well if it didn't. The same is true for NB. If it
111  // exists, but NA does not, NA must come after it. If neither exist, we need
112  // to number the block and cache the results instComesBefore.
113  const auto NAI = NumberedInsts.find(A);
114  const auto NBI = NumberedInsts.find(B);
115  if(NAI != NumberedInsts.end() && NBI != NumberedInsts.end())
116  {
117  return NAI->second < NBI->second;
118  }
119  if(NAI != NumberedInsts.end())
120  {
121  return B->get_kind() !=
122  gimple_phi_K; // Not found phi nodes have been just added from this step in front of all other phis
123  }
124  if(NBI != NumberedInsts.end())
125  {
126  return false;
127  }
128  THROW_ASSERT(A->get_kind() != gimple_phi_K, "Non dato, not given, nicht gegeben, pas donnĂ©, no dado, non detur");
129 
130  return instComesBefore(A, B);
131 }
132 
134 {
135 }
136 
137 bool OrderedInstructions::dominates(const unsigned int BBIA, const unsigned int BBIB) const
138 {
139  const auto& BBmap = DT->CGetBBGraphInfo()->bb_index_map;
140 
141  const auto BBAi_v = BBmap.find(BBIA);
142  const auto BBBi_v = BBmap.find(BBIB);
143 
144  if(BBIA == BBIB)
145  {
146  return true;
147  }
148 
149  if(BBAi_v->second == BBBi_v->second)
150  {
151  // Intermediate BB shadowing incoming BB
152  const auto& b_pred = DT->CGetBBNodeInfo(BBBi_v->second)->block->list_of_pred;
153  return std::find(b_pred.begin(), b_pred.end(), BBIA) != b_pred.end();
154  }
155  THROW_ASSERT(BBAi_v != BBmap.end(), "Unknown BB index (" + STR(BBIA) + ")");
156  THROW_ASSERT(BBBi_v != BBmap.end(), "Unknown BB index (" + STR(BBIB) + ")");
157 
158  // An unreachable block is dominated by anything.
159  if(!DT->IsReachable(BBmap.at(bloc::ENTRY_BLOCK_ID), BBBi_v->second))
160  {
161  return true;
162  }
163 
164  // And dominates nothing.
165  if(!DT->IsReachable(BBmap.at(bloc::ENTRY_BLOCK_ID), BBAi_v->second))
166  {
167  return false;
168  }
169 
172  if(DT->IsReachable(BBAi_v->second, BBBi_v->second))
173  {
174  return true;
175  }
176 
177  return false;
178 }
179 
180 bool OrderedInstructions::dominates(const struct gimple_node* InstA, const struct gimple_node* InstB) const
181 {
182  THROW_ASSERT(InstA, "Instruction A cannot be null");
183  THROW_ASSERT(InstB, "Instruction B cannot be null");
184 
185  const auto BBIA = InstA->bb_index;
186  const auto BBIB = InstB->bb_index;
187 
188  // Use ordered basic block to do dominance check in case the 2 instructions
189  // are in the same basic block.
190  if(BBIA == BBIB)
191  {
192  auto OBB = OBBMap.find(BBIA);
193  if(OBB == OBBMap.end())
194  {
195  const auto BBmap = DT->CGetBBGraphInfo()->bb_index_map;
196  const auto BBvertex = BBmap.find(BBIA);
197  THROW_ASSERT(BBvertex != BBmap.end(), "Unknown BB index (" + STR(BBIA) + ")");
198 
199  const auto BB = DT->CGetBBNodeInfo(BBvertex->second)->block;
200  THROW_ASSERT(BB->number == BBIA,
201  "Intermediate BB not allowed here"); // Intermediate BB shadows its incoming BB, thus its index
202  // is different from associated vertex
203  OBB = OBBMap.insert({BBIA, absl::make_unique<OrderedBasicBlock>(BB)}).first;
204  }
205  return OBB->second->dominates(InstA, InstB);
206  }
207 
208  return dominates(BBIA, BBIB);
209 }
210 
212 {
213  OBBMap.erase(BBI);
214 }
215 
217 {
218  return DT;
219 }
bool dominates(const unsigned int BBIA, const unsigned int BBIB) const
const BBGraphConstRef DT
The dominator tree of the parent function.
const blocRef BB
The source BasicBlock to map.
bool instComesBefore(const struct gimple_node *A, const struct gimple_node *B)
Given no cached results, find if A comes before B in BB.
bool dominates(const struct gimple_node *A, const struct gimple_node *B)
Find out whether A dominates B, meaning whether A comes before B in BB.
CustomMap< unsigned int, std::unique_ptr< OrderedBasicBlock > > OBBMap
Used to check dominance for instructions in same basic block.
exceptions managed by PandA
Data structure describing a basic block at tree level.
unsigned NextInstPos
The position/number to tag the next instruction to be found.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define A
Definition: generate.c:13
std::list< tree_nodeRef >::const_iterator LastInstFound
Keep track of last instruction inserted into NumberedInsts.
#define STR(s)
Macro which performs a lexical_cast to a string.
void invalidateBlock(unsigned int BBI)
Invalidate the OrderedBasicBlock cache when its basic block changes.
CustomMap< const struct gimple_node *, unsigned > NumberedInsts
Map a instruction to its position in a BasicBlock.
unsigned int bb_index
The basic block to which this gimple_node belongs.
Definition: tree_node.hpp:1134
const std::list< tree_nodeRef > & BBInst
The source BasicBlock instruction list.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
Classes specification of the tree_node data structures.
const BBGraphConstRef & getDT() const
OrderedBasicBlock(const blocRef &BasicB)
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
OrderedInstructions(BBGraphConstRef _DT)
Constructor.
Class specification of the basic_block structure.
struct definition of the common part of a gimple with virtual operands
Definition: tree_node.hpp:1078
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
#define B
Definition: generate.c:14
#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:50 for PandA-2024.02 by doxygen 1.8.13