/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/MachineModuleInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- llvm/CodeGen/MachineModuleInfo.cpp ----------------------*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | |
10 | | #include "llvm/CodeGen/MachineModuleInfo.h" |
11 | | #include "llvm/ADT/ArrayRef.h" |
12 | | #include "llvm/ADT/DenseMap.h" |
13 | | #include "llvm/ADT/PostOrderIterator.h" |
14 | | #include "llvm/ADT/StringRef.h" |
15 | | #include "llvm/ADT/TinyPtrVector.h" |
16 | | #include "llvm/CodeGen/MachineFunction.h" |
17 | | #include "llvm/CodeGen/Passes.h" |
18 | | #include "llvm/IR/BasicBlock.h" |
19 | | #include "llvm/IR/DebugInfo.h" |
20 | | #include "llvm/IR/DerivedTypes.h" |
21 | | #include "llvm/IR/Instructions.h" |
22 | | #include "llvm/IR/Module.h" |
23 | | #include "llvm/IR/Value.h" |
24 | | #include "llvm/IR/ValueHandle.h" |
25 | | #include "llvm/MC/MCContext.h" |
26 | | #include "llvm/MC/MCSymbol.h" |
27 | | #include "llvm/Pass.h" |
28 | | #include "llvm/Support/Casting.h" |
29 | | #include "llvm/Support/ErrorHandling.h" |
30 | | #include "llvm/Target/TargetLoweringObjectFile.h" |
31 | | #include "llvm/Target/TargetMachine.h" |
32 | | #include <algorithm> |
33 | | #include <cassert> |
34 | | #include <memory> |
35 | | #include <utility> |
36 | | #include <vector> |
37 | | |
38 | | using namespace llvm; |
39 | | using namespace llvm::dwarf; |
40 | | |
41 | | // Handle the Pass registration stuff necessary to use DataLayout's. |
42 | | INITIALIZE_PASS(MachineModuleInfo, "machinemoduleinfo", |
43 | | "Machine Module Information", false, false) |
44 | | char MachineModuleInfo::ID = 0; |
45 | | |
46 | | // Out of line virtual method. |
47 | 19.5k | MachineModuleInfoImpl::~MachineModuleInfoImpl() = default; |
48 | | |
49 | | namespace llvm { |
50 | | |
51 | | class MMIAddrLabelMapCallbackPtr final : CallbackVH { |
52 | | MMIAddrLabelMap *Map = nullptr; |
53 | | |
54 | | public: |
55 | | MMIAddrLabelMapCallbackPtr() = default; |
56 | 379 | MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} |
57 | | |
58 | 0 | void setPtr(BasicBlock *BB) { |
59 | 0 | ValueHandleBase::operator=(BB); |
60 | 0 | } |
61 | | |
62 | 379 | void setMap(MMIAddrLabelMap *map) { Map = map; } |
63 | | |
64 | | void deleted() override; |
65 | | void allUsesReplacedWith(Value *V2) override; |
66 | | }; |
67 | | |
68 | | class MMIAddrLabelMap { |
69 | | MCContext &Context; |
70 | | struct AddrLabelSymEntry { |
71 | | /// The symbols for the label. |
72 | | TinyPtrVector<MCSymbol *> Symbols; |
73 | | |
74 | | Function *Fn; // The containing function of the BasicBlock. |
75 | | unsigned Index; // The index in BBCallbacks for the BasicBlock. |
76 | | }; |
77 | | |
78 | | DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; |
79 | | |
80 | | /// Callbacks for the BasicBlock's that we have entries for. We use this so |
81 | | /// we get notified if a block is deleted or RAUWd. |
82 | | std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks; |
83 | | |
84 | | /// This is a per-function list of symbols whose corresponding BasicBlock got |
85 | | /// deleted. These symbols need to be emitted at some point in the file, so |
86 | | /// AsmPrinter emits them after the function body. |
87 | | DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>> |
88 | | DeletedAddrLabelsNeedingEmission; |
89 | | |
90 | | public: |
91 | 153 | MMIAddrLabelMap(MCContext &context) : Context(context) {} |
92 | | |
93 | 153 | ~MMIAddrLabelMap() { |
94 | 153 | assert(DeletedAddrLabelsNeedingEmission.empty() && |
95 | 153 | "Some labels for deleted blocks never got emitted"); |
96 | 153 | } |
97 | | |
98 | | ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); |
99 | | |
100 | | void takeDeletedSymbolsForFunction(Function *F, |
101 | | std::vector<MCSymbol*> &Result); |
102 | | |
103 | | void UpdateForDeletedBlock(BasicBlock *BB); |
104 | | void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); |
105 | | }; |
106 | | |
107 | | } // end namespace llvm |
108 | | |
109 | 1.01k | ArrayRef<MCSymbol *> MMIAddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { |
110 | 1.01k | assert(BB->hasAddressTaken() && |
111 | 1.01k | "Shouldn't get label for block without address taken"); |
112 | 1.01k | AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; |
113 | 1.01k | |
114 | 1.01k | // If we already had an entry for this block, just return it. |
115 | 1.01k | if (!Entry.Symbols.empty()1.01k ) { |
116 | 636 | assert(BB->getParent() == Entry.Fn && "Parent changed"); |
117 | 636 | return Entry.Symbols; |
118 | 636 | } |
119 | 379 | |
120 | 379 | // Otherwise, this is a new entry, create a new symbol for it and add an |
121 | 379 | // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. |
122 | 379 | BBCallbacks.emplace_back(BB); |
123 | 379 | BBCallbacks.back().setMap(this); |
124 | 379 | Entry.Index = BBCallbacks.size() - 1; |
125 | 379 | Entry.Fn = BB->getParent(); |
126 | 379 | Entry.Symbols.push_back(Context.createTempSymbol()); |
127 | 379 | return Entry.Symbols; |
128 | 379 | } |
129 | | |
130 | | /// If we have any deleted symbols for F, return them. |
131 | | void MMIAddrLabelMap:: |
132 | 89 | takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) { |
133 | 89 | DenseMap<AssertingVH<Function>, std::vector<MCSymbol*>>::iterator I = |
134 | 89 | DeletedAddrLabelsNeedingEmission.find(F); |
135 | 89 | |
136 | 89 | // If there are no entries for the function, just return. |
137 | 89 | if (I == DeletedAddrLabelsNeedingEmission.end()89 ) return89 ; |
138 | 0 |
|
139 | 0 | // Otherwise, take the list. |
140 | 0 | std::swap(Result, I->second); |
141 | 0 | DeletedAddrLabelsNeedingEmission.erase(I); |
142 | 0 | } |
143 | | |
144 | 0 | void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { |
145 | 0 | // If the block got deleted, there is no need for the symbol. If the symbol |
146 | 0 | // was already emitted, we can just forget about it, otherwise we need to |
147 | 0 | // queue it up for later emission when the function is output. |
148 | 0 | AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); |
149 | 0 | AddrLabelSymbols.erase(BB); |
150 | 0 | assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); |
151 | 0 | BBCallbacks[Entry.Index] = nullptr; // Clear the callback. |
152 | 0 |
|
153 | 0 | assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && |
154 | 0 | "Block/parent mismatch"); |
155 | 0 |
|
156 | 0 | for (MCSymbol *Sym : Entry.Symbols) { |
157 | 0 | if (Sym->isDefined()) |
158 | 0 | return; |
159 | 0 |
|
160 | 0 | // If the block is not yet defined, we need to emit it at the end of the |
161 | 0 | // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list |
162 | 0 | // for the containing Function. Since the block is being deleted, its |
163 | 0 | // parent may already be removed, we have to get the function from 'Entry'. |
164 | 0 | DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); |
165 | 0 | } |
166 | 0 | } |
167 | | |
168 | 0 | void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { |
169 | 0 | // Get the entry for the RAUW'd block and remove it from our map. |
170 | 0 | AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); |
171 | 0 | AddrLabelSymbols.erase(Old); |
172 | 0 | assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); |
173 | 0 |
|
174 | 0 | AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; |
175 | 0 |
|
176 | 0 | // If New is not address taken, just move our symbol over to it. |
177 | 0 | if (NewEntry.Symbols.empty()0 ) { |
178 | 0 | BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. |
179 | 0 | NewEntry = std::move(OldEntry); // Set New's entry. |
180 | 0 | return; |
181 | 0 | } |
182 | 0 |
|
183 | 0 | BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. |
184 | 0 |
|
185 | 0 | // Otherwise, we need to add the old symbols to the new block's set. |
186 | 0 | NewEntry.Symbols.insert(NewEntry.Symbols.end(), OldEntry.Symbols.begin(), |
187 | 0 | OldEntry.Symbols.end()); |
188 | 0 | } |
189 | | |
190 | 0 | void MMIAddrLabelMapCallbackPtr::deleted() { |
191 | 0 | Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); |
192 | 0 | } |
193 | | |
194 | 0 | void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { |
195 | 0 | Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); |
196 | 0 | } |
197 | | |
198 | | MachineModuleInfo::MachineModuleInfo(const TargetMachine *TM) |
199 | | : ImmutablePass(ID), TM(*TM), |
200 | | Context(TM->getMCAsmInfo(), TM->getMCRegisterInfo(), |
201 | 34.2k | TM->getObjFileLowering(), nullptr, false) { |
202 | 34.2k | initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry()); |
203 | 34.2k | } |
204 | | |
205 | 34.0k | MachineModuleInfo::~MachineModuleInfo() = default; |
206 | | |
207 | 34.0k | bool MachineModuleInfo::doInitialization(Module &M) { |
208 | 34.0k | ObjFileMMI = nullptr; |
209 | 34.0k | CurCallSite = 0; |
210 | 34.0k | DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false; |
211 | 34.0k | HasSplitStack = HasNosplitStack = false; |
212 | 34.0k | AddrLabelSymbols = nullptr; |
213 | 34.0k | TheModule = &M; |
214 | 34.0k | return false; |
215 | 34.0k | } |
216 | | |
217 | 33.9k | bool MachineModuleInfo::doFinalization(Module &M) { |
218 | 33.9k | Personalities.clear(); |
219 | 33.9k | |
220 | 33.9k | delete AddrLabelSymbols; |
221 | 33.9k | AddrLabelSymbols = nullptr; |
222 | 33.9k | |
223 | 33.9k | Context.reset(); |
224 | 33.9k | |
225 | 33.9k | delete ObjFileMMI; |
226 | 33.9k | ObjFileMMI = nullptr; |
227 | 33.9k | |
228 | 33.9k | return false; |
229 | 33.9k | } |
230 | | |
231 | | //===- Address of Block Management ----------------------------------------===// |
232 | | |
233 | | ArrayRef<MCSymbol *> |
234 | 1.01k | MachineModuleInfo::getAddrLabelSymbolToEmit(const BasicBlock *BB) { |
235 | 1.01k | // Lazily create AddrLabelSymbols. |
236 | 1.01k | if (!AddrLabelSymbols) |
237 | 153 | AddrLabelSymbols = new MMIAddrLabelMap(Context); |
238 | 1.01k | return AddrLabelSymbols->getAddrLabelSymbolToEmit(const_cast<BasicBlock*>(BB)); |
239 | 1.01k | } |
240 | | |
241 | | void MachineModuleInfo:: |
242 | | takeDeletedSymbolsForFunction(const Function *F, |
243 | 595k | std::vector<MCSymbol*> &Result) { |
244 | 595k | // If no blocks have had their addresses taken, we're done. |
245 | 595k | if (!AddrLabelSymbols595k ) return595k ; |
246 | 88 | return AddrLabelSymbols-> |
247 | 88 | takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result); |
248 | 88 | } |
249 | | |
250 | | /// \name Exception Handling |
251 | | /// \{ |
252 | | |
253 | 18.5k | void MachineModuleInfo::addPersonality(const Function *Personality) { |
254 | 18.5k | for (unsigned i = 0; i < Personalities.size()18.5k ; ++i6 ) |
255 | 18.0k | if (18.0k Personalities[i] == Personality18.0k ) |
256 | 18.0k | return; |
257 | 557 | Personalities.push_back(Personality); |
258 | 557 | } |
259 | | |
260 | | /// \} |
261 | | |
262 | | MachineFunction * |
263 | 2.33k | MachineModuleInfo::getMachineFunction(const Function &F) const { |
264 | 2.33k | auto I = MachineFunctions.find(&F); |
265 | 2.33k | return I != MachineFunctions.end() ? I->second.get()1 : nullptr2.33k ; |
266 | 2.33k | } |
267 | | |
268 | | MachineFunction & |
269 | 56.7M | MachineModuleInfo::getOrCreateMachineFunction(const Function &F) { |
270 | 56.7M | // Shortcut for the common case where a sequence of MachineFunctionPasses |
271 | 56.7M | // all query for the same Function. |
272 | 56.7M | if (LastRequest == &F) |
273 | 56.1M | return *LastResult; |
274 | 600k | |
275 | 600k | auto I = MachineFunctions.insert( |
276 | 600k | std::make_pair(&F, std::unique_ptr<MachineFunction>())); |
277 | 600k | MachineFunction *MF; |
278 | 600k | if (I.second600k ) { |
279 | 598k | // No pre-existing machine function, create a new one. |
280 | 598k | MF = new MachineFunction(&F, TM, NextFnNum++, *this); |
281 | 598k | // Update the set entry. |
282 | 598k | I.first->second.reset(MF); |
283 | 600k | } else { |
284 | 1.92k | MF = I.first->second.get(); |
285 | 1.92k | } |
286 | 56.7M | |
287 | 56.7M | LastRequest = &F; |
288 | 56.7M | LastResult = MF; |
289 | 56.7M | return *MF; |
290 | 56.7M | } |
291 | | |
292 | 598k | void MachineModuleInfo::deleteMachineFunctionFor(Function &F) { |
293 | 598k | MachineFunctions.erase(&F); |
294 | 598k | LastRequest = nullptr; |
295 | 598k | LastResult = nullptr; |
296 | 598k | } |
297 | | |
298 | | namespace { |
299 | | |
300 | | /// This pass frees the MachineFunction object associated with a Function. |
301 | | class FreeMachineFunction : public FunctionPass { |
302 | | public: |
303 | | static char ID; |
304 | | |
305 | 34.1k | FreeMachineFunction() : FunctionPass(ID) {} |
306 | | |
307 | 34.1k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
308 | 34.1k | AU.addRequired<MachineModuleInfo>(); |
309 | 34.1k | AU.addPreserved<MachineModuleInfo>(); |
310 | 34.1k | } |
311 | | |
312 | 598k | bool runOnFunction(Function &F) override { |
313 | 598k | MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); |
314 | 598k | MMI.deleteMachineFunctionFor(F); |
315 | 598k | return true; |
316 | 598k | } |
317 | | |
318 | 16 | StringRef getPassName() const override { |
319 | 16 | return "Free MachineFunction"; |
320 | 16 | } |
321 | | }; |
322 | | |
323 | | } // end anonymous namespace |
324 | | |
325 | | char FreeMachineFunction::ID; |
326 | | |
327 | 34.1k | FunctionPass *llvm::createFreeMachineFunctionPass() { |
328 | 34.1k | return new FreeMachineFunction(); |
329 | 34.1k | } |
330 | | |
331 | | //===- MMI building helpers -----------------------------------------------===// |
332 | | |
333 | | void llvm::computeUsesVAFloatArgument(const CallInst &I, |
334 | 2.16M | MachineModuleInfo &MMI) { |
335 | 2.16M | FunctionType *FT = |
336 | 2.16M | cast<FunctionType>(I.getCalledValue()->getType()->getContainedType(0)); |
337 | 2.16M | if (FT->isVarArg() && 2.16M !MMI.usesVAFloatArgument()48.9k ) { |
338 | 109k | for (unsigned i = 0, e = I.getNumArgOperands(); i != e109k ; ++i82.1k ) { |
339 | 82.7k | Type *T = I.getArgOperand(i)->getType(); |
340 | 339k | for (auto i : post_order(T)) { |
341 | 339k | if (i->isFloatingPointTy()339k ) { |
342 | 598 | MMI.setUsesVAFloatArgument(true); |
343 | 598 | return; |
344 | 598 | } |
345 | 339k | } |
346 | 82.7k | } |
347 | 27.2k | } |
348 | 2.16M | } |