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

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

Powered by Google App Engine
This is Rietveld 408576698