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

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