Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: lib/Transforms/NaCl/SimplifyStructRegSignatures.cpp

Issue 992493002: Lower signatures exposing struct registers to byval struct pointers (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Tests for invoke, array, vector, vararg Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===- SimplifyStructRegSignatures.cpp - struct regs to struct pointers----===//
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 // This pass replaces function signatures exposing struct registers
11 // to byval pointer-based signatures.
12 //
13 // There are 2 types of signatures that are thus changed:
14 //
15 // @foo(%some_struct %val) -> @foo(%some_struct* byval %val)
16 // and
17 // %someStruct @bar(<other_args>) -> void @bar(%someStruct* sret, <other_args>)
18 //
19 // Such function types may appear in other type declarations, for example:
20 //
21 // %a_struct = type { void (%some_struct)*, i32 }
22 //
23 // We map such types to corresponding types, mapping the function types
24 // appropriately:
25 //
26 // %a_struct.0 = type { void (%some_struct*)*, i32 }
27 //===----------------------------------------------------------------------===//
28
29 #include "llvm/ADT/SmallString.h"
30 #include "llvm/IR/IRBuilder.h"
31 #include "llvm/ADT/ArrayRef.h"
32 #include "llvm/ADT/DenseSet.h"
33 #include "llvm/ADT/ilist.h"
34 #include "llvm/ADT/SetVector.h"
35 #include "llvm/ADT/SmallVector.h"
36 #include "llvm/ADT/Twine.h"
37 #include "llvm/IR/Argument.h"
38 #include "llvm/IR/Attributes.h"
39 #include "llvm/IR/BasicBlock.h"
40 #include "llvm/IR/DebugInfo.h"
41 #include "llvm/IR/DerivedTypes.h"
42 #include "llvm/IR/Function.h"
43 #include "llvm/IR/GlobalValue.h"
44 #include "llvm/IR/Instructions.h"
45 #include "llvm/IR/Module.h"
46 #include "llvm/IR/Type.h"
47 #include "llvm/IR/Use.h"
48 #include "llvm/IR/User.h"
49 #include "llvm/IR/Value.h"
50 #include "llvm/Pass.h"
51 #include "llvm/PassInfo.h"
52 #include "llvm/PassRegistry.h"
53 #include "llvm/PassSupport.h"
54 #include "llvm/Transforms/NaCl.h"
55 #include "llvm/Support/Debug.h"
56
57 #include <cassert>
58 #include <cstddef>
59
60 using namespace llvm;
61
62 namespace {
63
64 static const unsigned int TypicalFuncArity = 8;
65 static const unsigned int TypicalStructArity = 8;
66
67 class MappingResult {
68 public:
69 MappingResult(Type *ATy, bool Chg) {
70 Ty = ATy;
71 Changed = Chg;
72 }
73
74 bool isChanged() { return Changed; }
75
76 Type *operator->() { return Ty; }
77
78 operator Type *() { return Ty; }
79
80 private:
81 Type *Ty;
82 bool Changed;
83 };
84
85 // Utility class. For any given type, get the associated type that is free of
86 // struct register arguments.
87 class TypeMapper {
88 public:
89 typedef DenseMap<StructType *, StructType *> StructMap;
90 Type *getSimpleType(LLVMContext &Ctx, Type *Ty);
91
92 private:
93 DenseMap<Type *, Type *> MappedTypes;
94 MappingResult getSimpleArgumentType(LLVMContext &Ctx, Type *Ty,
95 StructMap &Tentatives);
96 MappingResult getSimpleAggregateTypeInternal(LLVMContext &Ctx, Type *Ty,
97 StructMap &Tentatives);
98
99 bool isChangedStruct(LLVMContext &Ctx, StructType *StructTy,
100 SmallVector<Type *, TypicalStructArity> &ElemTypes,
101 StructMap &Tentatives);
102 };
103
104 // This is a ModulePass because the pass recreates functions in
105 // order to change their signatures.
106 class SimplifyStructRegSignatures : public ModulePass {
107 public:
108 static char ID;
109
110 SimplifyStructRegSignatures() : ModulePass(ID) {
111 initializeSimplifyStructRegSignaturesPass(*PassRegistry::getPassRegistry());
112 }
113 virtual bool runOnModule(Module &M);
114
115 private:
116 TypeMapper Mapper;
117 DenseSet<Function *> FunctionsToDelete;
118 SetVector<CallInst *> CallsToPatch;
119 SetVector<InvokeInst *> InvokesToPatch;
120 DenseMap<Function *, Function *> FunctionMap;
121 bool
122 simplifyFunction(LLVMContext &Ctx, Function *OldFunc,
123 DenseMap<const Function *, DISubprogram> &DISubprogramMap);
124 void scheduleCallsForCleanup(Function *NewFunc);
125 template <class TCall>
126 void fixCallSite(LLVMContext &Ctx, TCall *Call, unsigned PreferredAlignment);
127 void fixFunctionBody(LLVMContext &Ctx, Function *OldFunc, Function *NewFunc);
128
129 template <class TCall>
130 TCall *fixCallTargetAndArguments(LLVMContext &Ctx, IRBuilder<> &Builder,
131 TCall *OldCall, Value *NewTarget,
132 FunctionType *NewType,
133 Value *ExtraArg = nullptr);
134 };
135 }
136
137 char SimplifyStructRegSignatures::ID = 0;
138
139 INITIALIZE_PASS(
140 SimplifyStructRegSignatures, "simplify-struct-reg-signatures",
141 "Simplify function signatures by removing struct register parameters",
142 false, false)
143
144 // The type is "simple" if it does not recursively reference a
145 // function type with at least an operand (arg or return) typed as struct
146 // register.
147 Type *TypeMapper::getSimpleType(LLVMContext &Ctx, Type *Ty) {
148 auto Found = MappedTypes.find(Ty);
149 if (Found != MappedTypes.end()) {
150 return Found->second;
151 }
152
153 StructMap Tentatives;
154 auto Ret = getSimpleAggregateTypeInternal(Ctx, Ty, Tentatives);
155 assert(Tentatives.size() == 0);
156
157 if (!Ty->isStructTy()) {
158 // Structs are memoized in getSimpleAggregateTypeInternal.
159 MappedTypes[Ty] = Ret;
160 }
161 return Ret;
162 }
163
164 // Transforms any type that could transitively reference a function pointer
165 // into a simplified type.
166 // We enter this function trying to determine the mapping of a type. Because
167 // of how structs are handled (not interned by llvm - see further comments
168 // below) we may be working with temporary types - types (pointers, for example)
169 // transitively referencing "tentative" structs. For that reason, we do not
170 // memoize anything here, except for structs. The latter is so that we avoid
171 // unnecessary repeated creation of types (pointers, function types, etc),
172 // as we try to map a given type.
173 MappingResult
174 TypeMapper::getSimpleAggregateTypeInternal(LLVMContext &Ctx, Type *Ty,
175 StructMap &Tentatives) {
176 // Leverage the map for types we encounter on the way.
177 auto Found = MappedTypes.find(Ty);
178 if (Found != MappedTypes.end()) {
179 return {Found->second, Found->second != Ty};
180 }
181
182 if (auto *OldFnTy = dyn_cast<FunctionType>(Ty)) {
183 Type *OldRetType = OldFnTy->getReturnType();
184 Type *NewRetType = OldRetType;
185 Type *Void = Type::getVoidTy(Ctx);
186 SmallVector<Type *, TypicalFuncArity> NewArgs;
187 bool Changed = false;
188 // Struct register returns become the first parameter of the new FT.
189 // The new FT has void for the return type
190 if (OldRetType->isAggregateType()) {
191 NewRetType = Void;
192 Changed = true;
193 NewArgs.push_back(getSimpleArgumentType(Ctx, OldRetType, Tentatives));
194 }
195 for (auto OldParam : OldFnTy->params()) {
196 auto NewType = getSimpleArgumentType(Ctx, OldParam, Tentatives);
197 Changed |= NewType.isChanged();
198 NewArgs.push_back(NewType);
199 }
200 Type *NewFuncType =
201 FunctionType::get(NewRetType, NewArgs, OldFnTy->isVarArg());
202 return {NewFuncType, Changed};
203 }
204
205 if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
206 auto NewTy = getSimpleAggregateTypeInternal(
207 Ctx, PtrTy->getPointerElementType(), Tentatives);
208
209 return {NewTy->getPointerTo(PtrTy->getAddressSpace()), NewTy.isChanged()};
210 }
211
212 if (auto ArrTy = dyn_cast<ArrayType>(Ty)) {
213 auto NewTy = getSimpleAggregateTypeInternal(
214 Ctx, ArrTy->getArrayElementType(), Tentatives);
215 return {ArrayType::get(NewTy, ArrTy->getArrayNumElements()),
216 NewTy.isChanged()};
217 }
218
219 if (auto VecTy = dyn_cast<VectorType>(Ty)) {
220 auto NewTy = getSimpleAggregateTypeInternal(
221 Ctx, VecTy->getVectorElementType(), Tentatives);
222 return {VectorType::get(NewTy, VecTy->getVectorNumElements()),
223 NewTy.isChanged()};
224 }
225
226 // LLVM doesn't intern identified structs (the ones with a name). This,
227 // together with the fact that such structs can be recursive,
228 // complicates things a bit. We want to make sure that we only change
229 // "unsimplified" structs (those that somehow reference funcs that
230 // are not simple).
231 // We don't want to change "simplified" structs, otherwise converting
232 // instruction types will become trickier.
233 if (auto StructTy = dyn_cast<StructType>(Ty)) {
234 SmallVector<Type *, TypicalStructArity> ElemTypes;
235 if (!StructTy->isLiteral()) {
236 // Literals - struct without a name - cannot be recursive, so we
237 // don't need to form tentatives.
238 auto Found = Tentatives.find(StructTy);
239
240 // Having a tentative means we are in a recursion trying to map this
241 // particular struct, so arriving back to it is not a change.
242 // We will determine if this struct is actually
243 // changed by checking its other fields.
244 if (Found != Tentatives.end()) {
245 return {Found->second, false};
246 }
247 // We have never seen this struct, so we start a tentative.
248 std::string NewName = StructTy->getStructName();
249 NewName += ".simplified";
250 StructType *Tentative = StructType::create(Ctx, NewName);
251 Tentatives[StructTy] = Tentative;
252
253 bool Changed = isChangedStruct(Ctx, StructTy, ElemTypes, Tentatives);
254
255 Tentatives.erase(StructTy);
256 // We can now decide the mapping of the struct. We will register it
257 // early with MappedTypes, to avoid leaking tentatives unnecessarily.
258 // We are leaking the created struct here, but there is no way to
259 // correctly delete it.
260 if (!Changed) {
261 return {MappedTypes[StructTy] = StructTy, false};
262 } else {
263 Tentative->setBody(ElemTypes, StructTy->isPacked());
264 return {MappedTypes[StructTy] = Tentative, true};
265 }
266 } else {
267 bool Changed = isChangedStruct(Ctx, StructTy, ElemTypes, Tentatives);
268 return {MappedTypes[StructTy] =
269 StructType::get(Ctx, ElemTypes, StructTy->isPacked()),
270 Changed};
271 }
272 }
273
274 // Anything else stays the same.
275 return {Ty, false};
276 }
277
278 bool TypeMapper::isChangedStruct(
279 LLVMContext &Ctx, StructType *StructTy,
280 SmallVector<Type *, TypicalStructArity> &ElemTypes, StructMap &Tentatives) {
281 bool Changed = false;
282 unsigned StructElemCount = StructTy->getStructNumElements();
283 for (unsigned I = 0; I < StructElemCount; I++) {
284 auto NewElem = getSimpleAggregateTypeInternal(
285 Ctx, StructTy->getStructElementType(I), Tentatives);
286 ElemTypes.push_back(NewElem);
287 Changed |= NewElem.isChanged();
288 }
289 return Changed;
290 }
291
292 // Get the simplified type of a function argument.
293 MappingResult TypeMapper::getSimpleArgumentType(LLVMContext &Ctx, Type *Ty,
294 StructMap &Tentatives) {
295 // struct registers become pointers to simple structs
296 if (Ty->isAggregateType()) {
297 return MappingResult(
298 PointerType::get(getSimpleAggregateTypeInternal(Ctx, Ty, Tentatives),
299 0),
300 true);
301 }
302
303 return getSimpleAggregateTypeInternal(Ctx, Ty, Tentatives);
304 }
305
306 // Apply 'byval' to func arguments that used to be struct regs.
307 // Apply 'sret' to the argument corresponding to the return in the old
308 // signature.
309 static void ApplyByValAndSRet(Function *OldFunc, Function *NewFunc) {
310 // When calling addAttribute, the first one refers to the function, so we
311 // skip past that.
312 unsigned ArgOffset = 1;
313 if (OldFunc->getReturnType()->isAggregateType()) {
314 NewFunc->addAttribute(1, Attribute::AttrKind::StructRet);
315 ArgOffset++;
316 }
317
318 auto &NewArgList = NewFunc->getArgumentList();
319 auto NewArg = NewArgList.begin();
320 for (const Argument &OldArg : OldFunc->getArgumentList()) {
321 if (OldArg.getType()->isAggregateType()) {
322 NewFunc->addAttribute(NewArg->getArgNo() + ArgOffset,
323 Attribute::AttrKind::ByVal);
324 }
325 NewArg++;
326 }
327 }
328
329 // Update the arg names for a newly created function.
330 static void UpdateArgNames(Function *OldFunc, Function *NewFunc) {
331 auto NewArgIter = NewFunc->arg_begin();
332 if (OldFunc->getReturnType()->isAggregateType()) {
333 NewArgIter->setName("retVal");
334 NewArgIter++;
335 }
336
337 for (const Argument &OldArg : OldFunc->args()) {
338 Argument *NewArg = NewArgIter++;
339 NewArg->setName(OldArg.getName() +
340 (OldArg.getType()->isAggregateType() ? ".ptr" : ""));
341 }
342 }
343
344 // Replace all uses of an old value with a new one, disregarding the type. We
345 // correct the types after we wire the new parameters in, in fixFunctionBody.
346 static void BlindReplace(Value *Old, Value *New) {
347 for (auto UseIter = Old->use_begin(), E = Old->use_end(); E != UseIter;) {
348 Use &AUse = *(UseIter++);
349 AUse.set(New);
350 }
351 }
352
353 // Adapt the body of a function for the new arguments.
354 static void ConvertArgumentValue(Value *Old, Value *New,
355 Instruction *InsPoint) {
356 if (Old == New)
357 return;
358
359 if (Old->getType() == New->getType()) {
360 Old->replaceAllUsesWith(New);
361 New->takeName(Old);
362 return;
363 }
364
365 bool IsAggregateToPtr =
366 Old->getType()->isAggregateType() && New->getType()->isPointerTy();
367 BlindReplace(Old, (IsAggregateToPtr
368 ? new LoadInst(New, Old->getName() + ".sreg", InsPoint)
369 : New));
370 }
371
372 // Fix returns. Return true if fixes were needed.
373 static void FixReturn(Function *OldFunc, Function *NewFunc) {
374
375 Argument *FirstNewArg = NewFunc->getArgumentList().begin();
376
377 for (auto BIter = NewFunc->begin(), LastBlock = NewFunc->end();
378 LastBlock != BIter;) {
379 BasicBlock *BB = BIter++;
380 for (auto IIter = BB->begin(), LastI = BB->end(); LastI != IIter;) {
381 Instruction *Instr = IIter++;
382 if (ReturnInst *Ret = dyn_cast<ReturnInst>(Instr)) {
383 auto RetVal = Ret->getReturnValue();
384 IRBuilder<> Builder(Ret);
385 StoreInst *Store = Builder.CreateStore(RetVal, FirstNewArg);
386 Store->setAlignment(FirstNewArg->getParamAlignment());
387 Builder.CreateRetVoid();
388 Ret->eraseFromParent();
389 }
390 }
391 }
392 }
393
394 // TODO (mtrofin): is this comprehensive?
395 template <class TCall>
396 void CopyCallAttributesAndMetadata(TCall *Orig, TCall *NewCall) {
397 NewCall->setCallingConv(Orig->getCallingConv());
398 NewCall->setAttributes(NewCall->getAttributes().addAttributes(
399 Orig->getContext(), AttributeSet::FunctionIndex,
400 Orig->getAttributes().getFnAttributes()));
401 NewCall->takeName(Orig);
402 }
403
404 static InvokeInst *CreateCallFrom(InvokeInst *Orig, Value *Target,
405 ArrayRef<Value *> &Args,
406 IRBuilder<> &Builder) {
407 auto Ret = Builder.CreateInvoke(Target, Orig->getNormalDest(),
408 Orig->getUnwindDest(), Args);
409 CopyCallAttributesAndMetadata(Orig, Ret);
410 return Ret;
411 }
412
413 static CallInst *CreateCallFrom(CallInst *Orig, Value *Target,
414 ArrayRef<Value *> &Args, IRBuilder<> &Builder) {
415
416 CallInst *Ret = Builder.CreateCall(Target, Args);
417 Ret->setTailCallKind(Orig->getTailCallKind());
418 CopyCallAttributesAndMetadata(Orig, Ret);
419 return Ret;
420 }
421
422 // Fix a call site by handing return type changes and/or parameter type and
423 // attribute changes.
424 template <class TCall>
425 void SimplifyStructRegSignatures::fixCallSite(LLVMContext &Ctx, TCall *OldCall,
426 unsigned PreferredAlignment) {
427 Value *NewTarget = OldCall->getCalledValue();
428
429 if (Function *CalledFunc = dyn_cast<Function>(NewTarget)) {
430 NewTarget = this->FunctionMap[CalledFunc];
431 }
432 assert(NewTarget);
433
434 auto *NewType = cast<FunctionType>(
435 Mapper.getSimpleType(Ctx, NewTarget->getType())->getPointerElementType());
436
437 auto *OldRetType = OldCall->getType();
438 const bool IsSRet =
439 !OldCall->getType()->isVoidTy() && NewType->getReturnType()->isVoidTy();
440
441 IRBuilder<> Builder(OldCall);
442 if (IsSRet) {
443 auto *Alloca = Builder.CreateAlloca(OldRetType);
JF 2015/03/19 16:21:25 I just realized: the alloca needs to be on the fun
Mircea Trofin 2015/03/19 22:30:49 Done.
444 Alloca->takeName(OldCall);
445 Alloca->setAlignment(PreferredAlignment);
446
447 auto *NewCall = fixCallTargetAndArguments(Ctx, Builder, OldCall, NewTarget,
448 NewType, Alloca);
449 assert(NewCall);
450 LoadInst *Load = nullptr;
451 if (auto *Invoke = dyn_cast<InvokeInst>(OldCall)){
JF 2015/03/19 16:21:25 clang-format
Mircea Trofin 2015/03/19 22:30:49 Done.
452 auto *ContBlock = Invoke->getNormalDest();
453 IRBuilder<> ContBuilder(ContBlock->getFirstInsertionPt());
JF 2015/03/19 16:21:25 You could just change the insert point for the exi
Mircea Trofin 2015/03/19 22:30:49 Done.
454 Load = ContBuilder.CreateLoad(Alloca, Alloca->getName() + ".sreg");
455 }
456 else {
457 Load = Builder.CreateLoad(Alloca, Alloca->getName() + ".sreg");
458 }
459 Load->setAlignment(Alloca->getAlignment());
460 OldCall->replaceAllUsesWith(Load);
461 } else {
462 auto *NewCall =
463 fixCallTargetAndArguments(Ctx, Builder, OldCall, NewTarget, NewType);
464 OldCall->replaceAllUsesWith(NewCall);
465 }
466
467 OldCall->eraseFromParent();
468 }
469
470 template <class TCall>
471 TCall *SimplifyStructRegSignatures::fixCallTargetAndArguments(
472 LLVMContext &Ctx, IRBuilder<> &Builder, TCall *OldCall, Value *NewTarget,
473 FunctionType *NewType, Value *ExtraArg) {
474 SmallSetVector<unsigned, TypicalFuncArity> ByRefPlaces;
475 SmallVector<Value *, TypicalFuncArity> NewArgs;
476
477 unsigned argOffset = ExtraArg ? 1 : 0;
478 if (ExtraArg)
479 NewArgs.push_back(ExtraArg);
480
481 for (unsigned ArgPos = 0;
482 ArgPos < NewType->getFunctionNumParams() - argOffset; ArgPos++) {
483
484 Use &OldArgUse = OldCall->getOperandUse(ArgPos);
485 Value *OldArg = OldArgUse;
486 Type *OldArgType = OldArg->getType();
487 unsigned NewArgPos = OldArgUse.getOperandNo() + argOffset;
488 Type *NewArgType = NewType->getFunctionParamType(NewArgPos);
489
490 if (OldArgType != NewArgType && OldArgType->isAggregateType()) {
491 AllocaInst *Alloca =
492 Builder.CreateAlloca(OldArgType, nullptr, OldArg->getName() + ".ptr");
JF 2015/03/19 16:21:25 Same thing on the alloca.
Mircea Trofin 2015/03/19 22:30:49 Done. There was an implementation option to first
493 Builder.CreateStore(OldArg, Alloca);
494 ByRefPlaces.insert(NewArgPos);
495 NewArgs.push_back(Alloca);
496 } else {
497 NewArgs.push_back(OldArg);
498 }
499 }
500
501 ArrayRef<Value *> ArrRef = NewArgs;
502 TCall *NewCall = CreateCallFrom(OldCall, NewTarget, ArrRef, Builder);
503
504 // Copy the attributes over, and add byref/sret as necessary.
505 const AttributeSet &OldAttrSet = OldCall->getAttributes();
506 const AttributeSet &NewAttrSet = NewCall->getAttributes();
507
508 for (unsigned I = 0; I < NewCall->getNumArgOperands(); I++) {
509 NewCall->setAttributes(NewAttrSet.addAttributes(
510 Ctx, I + argOffset + 1, OldAttrSet.getParamAttributes(I + 1)));
511 if (ByRefPlaces.count(I)) {
512 NewCall->addAttribute(I + 1, Attribute::ByVal);
513 }
514 }
515
516 if (ExtraArg) {
517 NewAttrSet.addAttributes(Ctx, 1, OldAttrSet.getRetAttributes());
518 NewCall->addAttribute(1, Attribute::StructRet);
519 } else {
520 NewCall->setAttributes(NewAttrSet.addAttributes(
521 Ctx, AttributeSet::ReturnIndex, OldAttrSet.getRetAttributes()));
522 }
523 return NewCall;
524 }
525
526 void SimplifyStructRegSignatures::scheduleCallsForCleanup(Function *NewFunc) {
527 for (auto &BBIter : NewFunc->getBasicBlockList()) {
528 for (auto &IIter : BBIter.getInstList()) {
529 if (CallInst *Call = dyn_cast<CallInst>(&IIter)) {
530 CallsToPatch.insert(Call);
531 } else if (InvokeInst *Invoke = dyn_cast<InvokeInst>(&IIter)) {
532 InvokesToPatch.insert(Invoke);
533 }
534 }
535 }
536 }
537
538 // Change function body in the light of type changes.
539 void SimplifyStructRegSignatures::fixFunctionBody(LLVMContext &Ctx,
540 Function *OldFunc,
541 Function *NewFunc) {
542 if (NewFunc->empty())
543 return;
544
545 bool returnWasFixed = OldFunc->getReturnType()->isAggregateType();
546
547 Instruction *InsPoint = NewFunc->begin()->begin();
548 auto NewArgIter = NewFunc->arg_begin();
549 // Advance one more if we used to return a struct register.
550 if (returnWasFixed)
551 NewArgIter++;
552
553 // Wire new parameters in.
554 for (auto ArgIter = OldFunc->arg_begin(), E = OldFunc->arg_end();
555 E != ArgIter;) {
556 Argument *OldArg = ArgIter++;
557 Argument *NewArg = NewArgIter++;
558 ConvertArgumentValue(OldArg, NewArg, InsPoint);
559 }
560
561 // Now fix instruction types. We know that each value could only possibly be
562 // of a simplified type. At the end of this, call sites will be invalid, but
563 // we handle that afterwards, to make sure we have all the functions changed
564 // first (so that calls have valid targets)
565 for (auto BBIter = NewFunc->begin(), LBlock = NewFunc->end();
566 LBlock != BBIter;) {
567 auto Block = BBIter++;
568 for (auto IIter = Block->begin(), LIns = Block->end(); LIns != IIter;) {
569 auto Instr = IIter++;
570 Instr->mutateType(Mapper.getSimpleType(Ctx, Instr->getType()));
571 }
572 }
573 if (returnWasFixed)
574 FixReturn(OldFunc, NewFunc);
575 }
576
577 // Ensure function is simplified, returning true if the function
578 // had to be changed.
579 bool SimplifyStructRegSignatures::simplifyFunction(
580 LLVMContext &Ctx, Function *OldFunc,
581 DenseMap<const Function *, DISubprogram> &DISubprogramMap) {
582 auto *OldFT = OldFunc->getFunctionType();
583 auto *NewFT = cast<FunctionType>(Mapper.getSimpleType(Ctx, OldFT));
584
585 Function *&AssociatedFctLoc = FunctionMap[OldFunc];
586 if (NewFT != OldFT) {
587 auto *NewFunc = Function::Create(NewFT, OldFunc->getLinkage());
588 AssociatedFctLoc = NewFunc;
589
590 NewFunc->copyAttributesFrom(OldFunc);
591 OldFunc->getParent()->getFunctionList().insert(OldFunc, NewFunc);
592 NewFunc->takeName(OldFunc);
593
594 UpdateArgNames(OldFunc, NewFunc);
595 ApplyByValAndSRet(OldFunc, NewFunc);
596
597 NewFunc->getBasicBlockList().splice(NewFunc->begin(),
598 OldFunc->getBasicBlockList());
599
600 fixFunctionBody(Ctx, OldFunc, NewFunc);
601 FunctionsToDelete.insert(OldFunc);
602 auto Found = DISubprogramMap.find(OldFunc);
603 if (Found != DISubprogramMap.end())
604 Found->second.replaceFunction(NewFunc);
605 } else {
606 AssociatedFctLoc = OldFunc;
607 }
608 scheduleCallsForCleanup(AssociatedFctLoc);
609 return NewFT != OldFT;
610 }
611
612 bool SimplifyStructRegSignatures::runOnModule(Module &M) {
613 bool Changed = false;
614
615 const DataLayout *DL = M.getDataLayout();
616 unsigned PreferredAlignment = 0;
617 if (DL)
618 PreferredAlignment = DL->getStackAlignment();
619
620 LLVMContext &Ctx = M.getContext();
621 auto DISubprogramMap = makeSubprogramMap(M);
622
623 // Change function signatures and fix a changed function body by
624 // wiring the new arguments. Call sites are unchanged at this point.
625 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E;) {
626 Function *Func = Iter++;
627 Changed |= simplifyFunction(Ctx, Func, DISubprogramMap);
628 }
629
630 // Fix call sites.
631 for (auto &CallToFix : CallsToPatch) {
632 fixCallSite(Ctx, CallToFix, PreferredAlignment);
633 }
634
635 for (auto &InvokeToFix : InvokesToPatch) {
636 fixCallSite(Ctx, InvokeToFix, PreferredAlignment);
637 }
638
639 // Delete leftover functions - the ones with old signatures.
640 for (auto &ToDelete : FunctionsToDelete) {
641 ToDelete->eraseFromParent();
642 }
643
644 return Changed;
645 }
646
647 ModulePass *llvm::createSimplifyStructRegSignaturesPass() {
648 return new SimplifyStructRegSignatures();
649 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698