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

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

Powered by Google App Engine
This is Rietveld 408576698