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

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

Powered by Google App Engine
This is Rietveld 408576698