OpenASIP 2.2
Loading...
Searching...
No Matches
MachineDCE.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2012-2020 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file MachineDCE.cc
26 *
27 * Implementation of MachineDCE class.
28 *
29 * @author Mikael Lepistö
30 */
31
32//===-- MachineDCE.cc - Find unreachable functions for codegen --===//
33//
34// The LLVM Compiler Infrastructure
35//
36// This file is distributed under the University of Illinois Open Source
37// License. See LICENSE.TXT for details.
38//
39//===----------------------------------------------------------------------===//
40//
41// Simple symbol based bookkeeping of which functions are really referred in code.
42// Analyse is used by code generator finalization. (Removes unneeded functions)
43//
44//===----------------------------------------------------------------------===//
45
46#include <iostream>
47
48#include "MachineDCE.hh"
49
50using namespace llvm;
51
52// register as analysis pass...
53static RegisterPass<MachineDCE>
54R("machinedce","Symbol string based machine DCE for removing not used emulation functions", false, true);
55char MachineDCE::ID = 0;
56
57//#define DEBUG_MACHINE_DCE
58
59/**
60 * Returns true if can find startpoint.
61 */
62bool MachineDCE::canFindStart(const std::string& user, AvoidRecursionSet& avoid_recursion) {
63 if (avoid_recursion.find(&user) != avoid_recursion.end()) {
64 return false;
65 } else {
66 avoid_recursion.insert(&user);
67 }
68
69 // current function is actually the start point.. nice job.
70 if (baseUsers_.find(user) != baseUsers_.end()) {
71 return true;
72 }
73
74 UserList &usesList = usersOfValue_[user];
75
76 // check if this function is used by start point to be sure...
77 for (UserList::iterator i= usesList.begin(); i != usesList.end(); i++) {
78 if (canFindStart((*i), avoid_recursion)) {
79 return true;
80 }
81 }
82 return false;
83}
84
85void MachineDCE::addInitializer(const Constant* init, std::string& name) {
86
87 if (const GlobalValue* gv = dyn_cast<GlobalValue>(init)) {
88#ifdef DEBUG_MACHINE_DCE
89 errs() << "Added data " << name
90 << " to uses of value: " << gv->getName()
91 << " and " << name << " to baseUsers."
92 << "\n";
93#endif
94 baseUsers_.insert(name);
95 usersOfValue_[gv->getName().str()].insert(name);
96 }
97
98 if ((dyn_cast<ConstantArray>(init) != NULL) ||
99 (dyn_cast<ConstantStruct>(init) != NULL) ||
100 (dyn_cast<ConstantVector>(init) != NULL) ||
101 (dyn_cast<ConstantExpr>(init) != NULL)) {
102
103 for (unsigned i = 0, e = init->getNumOperands(); i != e; ++i) {
104 //init->getOperand(i)->dump();
105 //addInitializer(dyn_cast<const Constant*>(init->getOperand(i)), name);
106 addInitializer(cast<Constant>(init->getOperand(i)), name);
107 }
108 }
109}
110
112
113#ifdef DEBUG_MACHINE_DCE
114 std::cerr << "Initializing MachineDCE\n";
115#endif
116
117 for (Module::const_iterator f = M.begin(), e = M.end(); f != e; ++f) {
118 if (!(f->getName().equals("_start") ||
119 f->getName().equals("_exit")))
120 continue;
121 baseUsers_.insert(f->getName().data());
122#ifdef DEBUG_MACHINE_DCE
123 std::cerr << "Added " << f->getName().str()
124 << " to entry/exit functions"
125 << std::endl;
126 f->dump();
127#endif
128 continue;
129 }
130
131 // Go through global variables to find out.
132 for (Module::const_global_iterator i = M.global_begin();
133 i != M.global_end(); i++) {
134 std::string name = i->getName().str();
135
136 if (!i->hasInitializer()) {
137 continue;
138 assert(false && "No initializer. External linkage?");
139 }
140
141 const Constant* initializer = i->getInitializer();
142#if 0
143 const Type* type = initializer->getType();
144 errs() << "Data name: " << name
145 << "\ttype: " << type->getDescription() << "\n";
146#endif
147 addInitializer(initializer, name);
148 }
149
150 return true;
151}
152
153bool MachineDCE::runOnMachineFunction(MachineFunction &F) {
154 std::string funcName = F.getFunction().getName().str();
155
156 // add function to function map...
157 functionMappings_[funcName] = &F;
158
159 for (MachineFunction::const_iterator i = F.begin();
160 i != F.end(); i++) {
161 for (MachineBasicBlock::const_iterator j = i->begin();
162 j != i->end(); j++) {
163
164 for (unsigned k = 0; k < j->getNumOperands(); k++) {
165 const MachineOperand& mo = j->getOperand(k);
166
167 std::string moName;
168
169 if (mo.isGlobal()) {
170 moName = mo.getGlobal()->getName().str();
171 } else if (mo.isSymbol()) {
172 moName = mo.getSymbolName();
173 }
174
175 if (!moName.empty()) {
176 usersOfValue_[moName].insert(funcName);
177 }
178 }
179 }
180 }
181 return true;
182}
183
184
186
187 // errs() << "Finalizing MachineDCE\n";
188
189 // For all functions check that they are reached from entrypoint of module.
190 for (FunctionMap::iterator func = functionMappings_.begin();
191 func != functionMappings_.end(); ++func) {
192
193 AvoidRecursionSet avoid_recursion;
194
195 if (!canFindStart(func->first, avoid_recursion)) {
196#ifdef DEBUG_MACHINE_DCE
197 std::cerr << "Function was not referred add it to dce data: "
198 << func->first << "\n";
199#endif
200 removeableFunctions.insert(func->first);
201 }
202 }
203
204 return true;
205}
#define assert(condition)
static RegisterPass< MachineDCE > R("machinedce","Symbol string based machine DCE for removing not used emulation functions", false, true)
virtual bool runOnMachineFunction(MachineFunction &F) override
UserList baseUsers_
If users are traced to this list it means that function cannot be eliminated.
Definition MachineDCE.hh:82
std::set< std::string > UserList
Definition MachineDCE.hh:70
bool canFindStart(const std::string &user, AvoidRecursionSet &avoid_recursion)
Definition MachineDCE.cc:62
virtual bool doInitialization(Module &M) override
UnusedFunctionsList removeableFunctions
Definition MachineDCE.hh:97
virtual bool doFinalization(Module &M) override
UserRelations usersOfValue_
List of users of a symbol.
Definition MachineDCE.hh:78
std::set< const std::string * > AvoidRecursionSet
Definition MachineDCE.hh:72
void addInitializer(const Constant *init, std::string &name)
Definition MachineDCE.cc:85
FunctionMap functionMappings_
Function name to MachineFunction map.
Definition MachineDCE.hh:75
static char ID
Definition MachineDCE.hh:67