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

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: clang-format -ed 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 <cassert>
30 #include <cstddef>
31 #include <llvm/ADT/SmallString.h>
32
33 #include "llvm/ADT/ArrayRef.h"
34 #include "llvm/ADT/DenseSet.h"
35 #include "llvm/ADT/ilist.h"
36 #include "llvm/ADT/SetVector.h"
37 #include "llvm/ADT/SmallVector.h"
38 #include "llvm/ADT/Twine.h"
39 #include "llvm/IR/Argument.h"
40 #include "llvm/IR/Attributes.h"
41 #include "llvm/IR/BasicBlock.h"
42 #include "llvm/IR/DerivedTypes.h"
43 #include "llvm/IR/Function.h"
44 #include "llvm/IR/GlobalValue.h"
45 #include "llvm/IR/Instructions.h"
46 #include "llvm/IR/Module.h"
47 #include "llvm/IR/Type.h"
48 #include "llvm/IR/Use.h"
49 #include "llvm/IR/User.h"
50 #include "llvm/IR/Value.h"
51 #include "llvm/Pass.h"
52 #include "llvm/PassInfo.h"
53 #include "llvm/PassRegistry.h"
54 #include "llvm/PassSupport.h"
55 #include "llvm/Transforms/NaCl.h"
56 #include "llvm/Support/Debug.h"
57
58 using namespace llvm;
59
60 namespace {
61 class MappingResult {
62 public:
63 MappingResult(Type *ATy, bool Chg) {
64 Ty = ATy;
65 Changed = Chg;
66 }
67
68 bool isChanged() { return Changed; }
69
70 Type *operator->() { return Ty; }
71
72 operator Type *() { return Ty; }
73
74 private:
75 Type *Ty;
76 bool Changed;
77 };
78
79 // Utility class. For any given type, get the associated type that is free of
80 // struct register arguments.
81 class TypeMapper {
82 public:
83 Type *getSimpleType(Type *Ty);
84
85 private:
86 DenseMap<Type *, Type *> MappedTypes;
87 MappingResult getSimpleArgumentType(Type *Ty);
88 MappingResult getSimpleAggregateTypeInternal(Type *Ty);
89 };
90
91 // This is a ModulePass because the pass recreates functions in
92 // order to change their signatures.
93 class SimplifyStructRegSignatures : public ModulePass {
94 public:
95 static char ID;
96
97 SimplifyStructRegSignatures() : ModulePass(ID) {
98 initializeSimplifyStructRegSignaturesPass(*PassRegistry::getPassRegistry());
99 }
100 virtual bool runOnModule(Module &M);
101
102 private:
103 unsigned PreferredAlignment = 0;
104 TypeMapper Mapper;
105 DenseSet<Function *> FunctionsToDelete;
106 SetVector<CallInst *> CallsToPatch;
107 SetVector<InvokeInst *> InvokesToPatch;
108 DenseMap<Function *, Function *> FunctionMap;
109 bool simplifyFunction(Function *OldFunc, Module &M);
110 void scheduleCallsForCleanup(Function *NewFunc);
111 template <class TCall> void fixCallSite(TCall *Call);
112 void fixFunctionBody(Function *OldFunc, Function *NewFunc);
113 };
114 }
115
116 static const unsigned int TypicalFuncArity = 8;
117 static const unsigned int TypicalStructArity = 8;
118
119 char SimplifyStructRegSignatures::ID = 0;
120
121 INITIALIZE_PASS(
122 SimplifyStructRegSignatures, "simplify-struct-reg-signatures",
123 "Simplify function signatures by removing struct register parameters",
124 false, false)
125
126 // The type is "simple" if it does not recursively reference a
127 // function type with at least an operand (arg or return) typed as struct
128 // register
129 Type *TypeMapper::getSimpleType(Type *Ty) {
130 return getSimpleAggregateTypeInternal(Ty);
131 }
132
133 // Transforms any type that could transitively reference a function pointer
134 // into a simplified type.
135 // We enter this function trying to determine the mapping of a type. Because
136 // of how structs are handled (not interned - see further comments below)
137 // we may be working with temporary types - types referencing "tentative"
138 // structs.
139 // TODO(mtrofin): is there a more maintainable algorithm?
140 MappingResult TypeMapper::getSimpleAggregateTypeInternal(Type *Ty) {
141 auto Found = MappedTypes.find(Ty);
142 if (Found != MappedTypes.end())
143 return {Found->second, false};
144
145 LLVMContext &Ctx = Ty->getContext();
JF 2015/03/14 18:42:58 You can have a single getContext in this file in r
Mircea Trofin 2015/03/16 18:38:45 Done.
146
147 if (auto *OldFnTy = dyn_cast<FunctionType>(Ty)) {
148 Type *OldRetType = OldFnTy->getReturnType();
149 Type *NewRetType = OldRetType;
150 Type *Void = Type::getVoidTy(Ctx);
151 SmallVector<Type *, TypicalFuncArity> NewArgs;
152 bool Changed = false;
153 // struct register returns become the first parameter of the new FT.
154 // the new FT has void for the return type
JF 2015/03/14 18:42:58 Capitalize and punctuation on comments, here and e
Mircea Trofin 2015/03/16 18:38:45 Done.
JF 2015/03/16 21:53:47 Punctuation is still missing in a few places.
155 if (OldRetType->isAggregateType()) {
156 NewRetType = Void;
157 Changed = true;
158 NewArgs.push_back(getSimpleArgumentType(OldRetType));
159 }
160 for (auto OldParam : OldFnTy->params()) {
161 auto NewType = getSimpleArgumentType(OldParam);
162 Changed |= NewType.isChanged();
163 NewArgs.push_back(NewType);
164 }
165 Type *NewFuncType =
166 FunctionType::get(NewRetType, NewArgs, OldFnTy->isVarArg());
167 return {NewFuncType, Changed};
168 }
169
170 if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
171 auto NewTy = getSimpleAggregateTypeInternal(PtrTy->getPointerElementType());
172
173 return {NewTy->getPointerTo(PtrTy->getAddressSpace()), NewTy.isChanged()};
174 }
175
176 if (auto ArrTy = dyn_cast<ArrayType>(Ty)) {
177 auto NewTy = getSimpleAggregateTypeInternal(ArrTy->getArrayElementType());
178 return {ArrayType::get(NewTy, ArrTy->getArrayNumElements()),
179 NewTy.isChanged()};
180 }
181
182 if (auto VecTy = dyn_cast<VectorType>(Ty)) {
183 auto NewTy = getSimpleAggregateTypeInternal(VecTy->getVectorElementType());
184 return {VectorType::get(NewTy, VecTy->getVectorNumElements()),
185 NewTy.isChanged()};
186 }
187
188 if (auto StructTy = dyn_cast<StructType>(Ty)) {
189 if (!StructTy->isLiteral()) {
190 // LLVM doesn't intern identified structs (the ones with a name). This,
191 // together with the fact that such structs can be recursive,
192 // complicates things a bit. We want to make sure that we only change
193 // "unsimplified" structs (those that somehow reference funcs that
194 // are not simple).
195 // We don't want to change "simplified" structs, otherwise converting
196 // instruction types will become trickier.
197 auto CandidateMapping = MappedTypes.find(Ty);
198 if (CandidateMapping == MappedTypes.end()) {
JF 2015/03/14 18:42:58 I would flip the polarity of this: if (... != en
199 // We don't have a mapping, and we don't know if the struct is recursive
200 // so we create an empty one and hypothesize that it is the
201 // mapping.
202 SmallString<256> Storage;
203 Twine NewName = StructTy->getStructName() + ".simplified";
JF 2015/03/14 18:42:58 You can 's/Twine/StringRef/' and drop the Storage.
Mircea Trofin 2015/03/16 18:38:45 If StructType::create accepted a Twine &, that'd w
JF 2015/03/16 21:53:46 Twine has a StringRef ctor, so it'll work. All you
204 MappedTypes[Ty] = StructType::create(Ctx, NewName.toStringRef(Storage));
205 } else {
206 // We either have a finished mapping or this is the empty placeholder
207 // created above, and we are in the process of finalizing it.
208 // 1) if this is a mapping, it must have the same element count
209 // as the original struct, so we mark a change if the types are
210 // different objects
211 // 2) if this is a placeholder, the element count
212 // getStructNumElements() sill differ.
213 // Since we don't know yet if this is a change or not - because we
214 // are constructing the mapping - we don't mark as change. We decide
215 // if it is a change below, based on the other struct elements.
216 Type *CurrentlyMapped = CandidateMapping->second;
JF 2015/03/14 18:42:58 You could cast<StructType>(CandidateMapping->secon
217 assert(CurrentlyMapped->isStructTy());
218 bool Changed = StructTy != CurrentlyMapped &&
219 StructTy->getStructNumElements() ==
220 CurrentlyMapped->getStructNumElements();
221 return {CurrentlyMapped, Changed};
222 }
223 }
224
225 SmallVector<Type *, TypicalStructArity> ElemTypes;
226 bool Changed = false;
227 unsigned StructElemCount = StructTy->getStructNumElements();
228 for (unsigned I = 0; I < StructElemCount; I++) {
229 auto NewElem =
230 getSimpleAggregateTypeInternal(Ty->getStructElementType(I));
231 ElemTypes.push_back(NewElem);
232 Changed |= NewElem.isChanged();
233 }
234 if (!Changed) {
235 // We are leaking the created struct here, but there is no way to
236 // correctly delete it.
237 // Replace whatever mapping we had with Ty
238 return {MappedTypes[Ty] = Ty, false};
239 }
240
241 if (StructTy->isLiteral()) {
242 return {MappedTypes[Ty] =
243 StructType::get(Ctx, ElemTypes, StructTy->isPacked()),
244 Changed};
245 } else {
246 // Lookup the mapping again, as it may have been changed/replaced
247 auto CandidateMapping = MappedTypes.find(Ty);
248 StructType *NewStruct = dyn_cast<StructType>(CandidateMapping->second);
249 assert(NewStruct);
JF 2015/03/14 18:42:58 You can just use cast<> instead of dyn_cast<>, and
Mircea Trofin 2015/03/16 18:38:45 Done.
250 NewStruct->setBody(ElemTypes, StructTy->isPacked());
251 return {NewStruct, true};
252 }
253 }
254
255 // Anything else stays the same.
256 return {Ty, false};
257 }
258
259 // get the simplified type of a function argument.
260 MappingResult TypeMapper::getSimpleArgumentType(Type *Ty) {
261 // struct registers become pointers to simple structs
262 if (Ty->isAggregateType()) {
263 return MappingResult(
264 PointerType::get(getSimpleAggregateTypeInternal(Ty), 0), true);
265 }
266
267 return getSimpleAggregateTypeInternal(Ty);
268 }
269
270 // apply 'byval' to func arguments that used to be struct regs.
271 // apply 'sret' to the argument corresponding to the return in the old signature
272 static void ApplyByValAndSRet(Function *OldFunc, Function *NewFunc) {
273 // when calling addAttribute, the first one refers to the function, so we
274 // skip past that.
275 unsigned ArgOffset = 1;
276 if (OldFunc->getReturnType()->isAggregateType()) {
277 NewFunc->addAttribute(1, Attribute::AttrKind::StructRet);
278 ArgOffset++;
279 }
280
281 auto &NewArgList = NewFunc->getArgumentList();
282 auto NewArg = NewArgList.begin();
283 for (const Argument &OldArg : OldFunc->getArgumentList()) {
284 if (OldArg.getType()->isAggregateType()) {
285 NewFunc->addAttribute(NewArg->getArgNo() + ArgOffset,
286 Attribute::AttrKind::ByVal);
287 }
288 NewArg++;
289 }
290 }
291
292 // update the arg names for a newly created function
293 static void UpdateArgNames(Function *OldFunc, Function *NewFunc) {
294 auto NewArgIter = NewFunc->arg_begin();
295 if (OldFunc->getReturnType()->isAggregateType()) {
296 NewArgIter->setName("retVal");
297 NewArgIter++;
298 }
299
300 for (const Argument &OldArg : OldFunc->args()) {
301 Argument *NewArg = NewArgIter++;
302 if (OldArg.getType()->isAggregateType()) {
303 NewArg->setName(OldArg.getName() + ".ptr");
304 } else {
305 NewArg->setName(OldArg.getName());
306 }
JF 2015/03/14 18:42:58 Personal style, I'd go with: NewArg->setName(Old
Mircea Trofin 2015/03/16 18:38:45 Done.
307 }
308 }
309
310 // Replace all uses of an old value with a new one, disregarding the type. We
311 // correct the types after we wire the new parameters in, in fixFunctionBody.
312 static void BlindReplace(Value *Old, Value *New) {
313 for (auto UseIter = Old->use_begin(), E = Old->use_end(); E != UseIter;) {
314 Use &AUse = *(UseIter++);
315 AUse.set(New);
316 }
317 }
318
319 // Adapt the body of a function for the new arguments.
320 static void ConvertArgumentValue(Value *Old, Value *New,
321 Instruction *InsPoint) {
322 if (Old == New)
323 return;
324
325 if (Old->getType() == New->getType()) {
326 Old->replaceAllUsesWith(New);
327 New->takeName(Old);
328 return;
329 }
330
331 if (Old->getType()->isAggregateType() && New->getType()->isPointerTy()) {
332 Value *Load = new LoadInst(New, Old->getName() + ".sreg", InsPoint);
333 BlindReplace(Old, Load);
334 } else {
335 BlindReplace(Old, New);
336 }
JF 2015/03/14 18:42:59 Same persona style here, I'd do: bool isAggregateT
Mircea Trofin 2015/03/16 18:38:45 Done.
337 }
338
339 // Fix returns. Return true if fixes were needed.
340 static void FixReturn(Function *OldFunc, Function *NewFunc) {
341
342 Argument *FirstNewArg = NewFunc->getArgumentList().begin();
343 auto &Ctx = NewFunc->getContext();
344
345 for (auto BIter = NewFunc->begin(), LastBlock = NewFunc->end();
346 LastBlock != BIter;) {
347 BasicBlock *BB = BIter++;
348 for (auto IIter = BB->begin(), LastI = BB->end(); LastI != IIter;) {
349 Instruction *Instr = IIter++;
350 if (ReturnInst *Ret = dyn_cast<ReturnInst>(Instr)) {
351 auto RetVal = Ret->getReturnValue();
352 ReturnInst *NewRet = ReturnInst::Create(Ctx, nullptr, Ret);
353 StoreInst *Store = new StoreInst(RetVal, FirstNewArg, NewRet);
354 Store->setAlignment(FirstNewArg->getParamAlignment());
355 Store->setDebugLoc(Ret->getDebugLoc());
356 Ret->eraseFromParent();
357 Ret = nullptr;
JF 2015/03/14 18:42:58 No point in setting Ret to nullptr since it's goin
Mircea Trofin 2015/03/16 18:38:45 Maintainability - makes it clear that Ret is inval
358 }
359 }
360 }
361 }
362
363 // TODO (mtrofin): is this comprehensive?
364 template <class TCall>
365 void CopyCallAttributesAndMetadata(TCall *Orig, TCall *NewCall) {
366 NewCall->setCallingConv(Orig->getCallingConv());
367 NewCall->setAttributes(NewCall->getAttributes().addAttributes(
368 Orig->getContext(), AttributeSet::FunctionIndex,
369 Orig->getAttributes().getFnAttributes()));
370 NewCall->setDebugLoc(Orig->getDebugLoc());
371 NewCall->takeName(Orig);
372 }
373
374 static InvokeInst *CreateCallFrom(InvokeInst *Orig, Value *Target,
375 ArrayRef<Value *> &Args) {
376 InvokeInst *Ret = InvokeInst::Create(Target, Orig->getNormalDest(),
377 Orig->getUnwindDest(), Args);
378 CopyCallAttributesAndMetadata(Orig, Ret);
379 return Ret;
380 }
381
382 static CallInst *CreateCallFrom(CallInst *Orig, Value *Target,
383 ArrayRef<Value *> &Args) {
384
385 CallInst *Ret = CallInst::Create(Target, Args);
386 Ret->setTailCallKind(Orig->getTailCallKind());
387 CopyCallAttributesAndMetadata(Orig, Ret);
388 return Ret;
389 }
390
391 // Fix a call site by handing return type changes and/or parameter type and
392 // attribute changes.
393 template <class TCall>
394 void SimplifyStructRegSignatures::fixCallSite(TCall *OldCall) {
395 Value *NewTarget = OldCall->getCalledValue();
396
397 if (Function *CalledFunc = dyn_cast<Function>(NewTarget)) {
398 NewTarget = this->FunctionMap[CalledFunc];
399 }
400 assert(NewTarget);
401
402 FunctionType *NewType = cast<FunctionType>(
403 Mapper.getSimpleType(NewTarget->getType())->getPointerElementType());
404
405 Type *OldRetType = OldCall->getType();
406 const bool isSRet =
407 !OldCall->getType()->isVoidTy() && NewType->getReturnType()->isVoidTy();
408
409 const unsigned argOffset = isSRet ? 1 : 0;
410
411 SmallVector<Value *, TypicalFuncArity> NewArgs;
412
413 if (isSRet) {
414 AllocaInst *Alloca = new AllocaInst(OldRetType);
415 Alloca->takeName(OldCall);
416 Alloca->insertBefore(OldCall);
417 Alloca->setAlignment(PreferredAlignment);
418 NewArgs.push_back(Alloca);
419
420 LoadInst *Load = new LoadInst(Alloca, Alloca->getName() + ".sreg",
421 (Instruction *)nullptr);
422 Load->setAlignment(Alloca->getAlignment());
423 Load->insertAfter(OldCall);
424 OldCall->replaceAllUsesWith(Load);
425 }
426
427 SmallSetVector<unsigned, TypicalFuncArity> ByRefPlaces;
428
429 for (unsigned ArgPos = 0;
430 ArgPos < NewType->getFunctionNumParams() - argOffset; ArgPos++) {
431
432 Use &OldArgUse = OldCall->getOperandUse(ArgPos);
433 Value *OldArg = OldArgUse;
434 Type *OldArgType = OldArg->getType();
435 unsigned NewArgPos = OldArgUse.getOperandNo() + argOffset;
436 Type *NewArgType = NewType->getFunctionParamType(NewArgPos);
437
438 if (OldArgType != NewArgType && OldArgType->isAggregateType()) {
439 AllocaInst *Alloca =
440 new AllocaInst(OldArgType, OldArg->getName() + ".ptr", OldCall);
441 new StoreInst(OldArg, Alloca, OldCall);
442 ByRefPlaces.insert(NewArgPos);
443 NewArgs.push_back(Alloca);
444 } else {
445 NewArgs.push_back(OldArg);
446 }
447 }
448
449 ArrayRef<Value *> ArrRef = NewArgs;
450 TCall *NewCall = CreateCallFrom(OldCall, NewTarget, ArrRef);
451
452 // copy the attributes over, and add byref/sret as necessary
453 const AttributeSet &OldAttrSet = OldCall->getAttributes();
454 const AttributeSet &NewAttrSet = NewCall->getAttributes();
455 LLVMContext &Ctx = OldCall->getContext();
456 AttrBuilder Builder(OldAttrSet, 0);
457
458 for (unsigned I = 0; I < NewCall->getNumArgOperands(); I++) {
459 NewCall->setAttributes(NewAttrSet.addAttributes(
460 Ctx, I + argOffset + 1, OldAttrSet.getParamAttributes(I + 1)));
461 if (ByRefPlaces.count(I)) {
462 NewCall->addAttribute(I + 1, Attribute::AttrKind::ByVal);
463 }
464 }
465
466 if (isSRet) {
467 NewAttrSet.addAttributes(Ctx, 1, OldAttrSet.getRetAttributes());
468 NewCall->addAttribute(1, Attribute::AttrKind::StructRet);
469 } else {
470 NewCall->setAttributes(NewAttrSet.addAttributes(
471 Ctx, AttributeSet::ReturnIndex, OldAttrSet.getRetAttributes()));
472 // if we still return something, this is the value to replace the old
473 // call with
474 OldCall->replaceAllUsesWith(NewCall);
475 }
476
477 NewCall->insertBefore(OldCall);
478 OldCall->eraseFromParent();
479 OldCall = NULL;
JF 2015/03/14 18:42:58 nullptr, but there's no point in doing this since
Mircea Trofin 2015/03/16 18:38:45 Just maintainability, clarifies the effect of eras
480 }
481
482 void SimplifyStructRegSignatures::scheduleCallsForCleanup(Function *NewFunc) {
483 for (auto &BBIter : NewFunc->getBasicBlockList()) {
484 for (auto &IIter : BBIter.getInstList()) {
485 if (CallInst *Call = dyn_cast<CallInst>(&IIter)) {
486 CallsToPatch.insert(Call);
487 } else if (InvokeInst *Invoke = dyn_cast<InvokeInst>(&IIter)) {
488 InvokesToPatch.insert(Invoke);
489 }
490 }
491 }
492 }
493
494 // Change function body in the light of type changes.
495 void SimplifyStructRegSignatures::fixFunctionBody(Function *OldFunc,
496 Function *NewFunc) {
497 if (NewFunc->empty())
498 return;
499
500 bool returnWasFixed = OldFunc->getReturnType()->isAggregateType();
501
502 Instruction *InsPoint = NewFunc->begin()->begin();
503 auto NewArgIter = NewFunc->arg_begin();
504 // advance one more if we used to return a struct register
505 if (returnWasFixed)
506 NewArgIter++;
507
508 // wire new parameters in
509 for (auto ArgIter = OldFunc->arg_begin(), E = OldFunc->arg_end();
510 E != ArgIter;) {
511 Argument *OldArg = ArgIter++;
512 Argument *NewArg = NewArgIter++;
513 ConvertArgumentValue(OldArg, NewArg, InsPoint);
514 }
515
516 // Now fix instruction types. Calls are dealt with separately, but we still
517 // update the types here. We know that each value could only possibly be
518 // of a simplified type. At the end of this, call sites will be invalid, but
519 // we handle that afterwards, to make sure we have all the functions changed
520 // first (so that calls have valid targets)
521 for (auto BBIter = NewFunc->begin(), LBlock = NewFunc->end();
522 LBlock != BBIter;) {
523 auto Block = BBIter++;
524 for (auto IIter = Block->begin(), LIns = Block->end(); LIns != IIter;) {
525 auto Instr = IIter++;
526 Instr->mutateType(Mapper.getSimpleType(Instr->getType()));
527 }
528 }
529 if (returnWasFixed)
530 FixReturn(OldFunc, NewFunc);
531 }
532
533 // Ensure function is simplified, returning true if the function
534 // had to be changed.
535 bool SimplifyStructRegSignatures::simplifyFunction(Function *OldFunc,
536 Module &M) {
537 FunctionType *OldFT = OldFunc->getFunctionType();
538 FunctionType *NewFT = dyn_cast<FunctionType>(Mapper.getSimpleType(OldFT));
539 assert(NewFT);
JF 2015/03/14 18:42:58 cast<FunctionType> above, drop the assert.
540
541 Function *&AssociatedFctLoc = FunctionMap[OldFunc];
542 if (NewFT != OldFT) {
543 Function *NewFunc = Function::Create(NewFT, OldFunc->getLinkage());
544 AssociatedFctLoc = NewFunc;
545
546 NewFunc->copyAttributesFrom(OldFunc);
547 OldFunc->getParent()->getFunctionList().insert(OldFunc, NewFunc);
548 NewFunc->takeName(OldFunc);
549
550 UpdateArgNames(OldFunc, NewFunc);
551 ApplyByValAndSRet(OldFunc, NewFunc);
552
553 NewFunc->getBasicBlockList().splice(NewFunc->begin(),
554 OldFunc->getBasicBlockList());
555
556 fixFunctionBody(OldFunc, NewFunc);
557 FunctionsToDelete.insert(OldFunc);
558 } else {
559 AssociatedFctLoc = OldFunc;
560 }
561 scheduleCallsForCleanup(AssociatedFctLoc);
562 return NewFT != OldFT;
563 }
564
565 bool SimplifyStructRegSignatures::runOnModule(Module &M) {
566 bool Changed = false;
567
568 const DataLayout *DL = M.getDataLayout();
569 if (DL)
570 PreferredAlignment = DL->getStackAlignment();
571
572 // change function signatures and fix a changed function body by
573 // wiring the new arguments. Call sites are unchanged at this point
574 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E;) {
575 Function *Func = Iter++;
576 Changed |= simplifyFunction(Func, M);
577 }
578
579 // fix call sites
580 for (auto &CallToFix : CallsToPatch) {
581 fixCallSite(CallToFix);
582 }
583
584 for (auto &InvokeToFix : InvokesToPatch) {
585 fixCallSite(InvokeToFix);
586 }
587
588 // delete leftover functions - the ones with old signatures
589 for (auto &ToDelete : FunctionsToDelete) {
590 // this also frees the memory
591 ToDelete->eraseFromParent();
592 }
593 return Changed;
594 }
595
596 ModulePass *llvm::createSimplifyStructRegSignaturesPass() {
597 return new SimplifyStructRegSignatures();
598 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698