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

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: Final. 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 // Insert Alloca at a specified location (normally, beginning of function)
425 // to avoid memory leaks if reason for inserting the Alloca
426 // (typically a call/invoke) is in a loop.
427 static AllocaInst *InsertAllocaAtLocation(IRBuilder<> &Builder,
428 BasicBlock::iterator &AllocaInsPoint,
429 Type *ValType) {
430 auto SavedInsPoint = Builder.GetInsertPoint();
431 Builder.SetInsertPoint(AllocaInsPoint);
432 auto *Alloca = Builder.CreateAlloca(ValType);
433 AllocaInsPoint = Builder.GetInsertPoint();
434 Builder.SetInsertPoint(SavedInsPoint);
435 return Alloca;
436 }
437
438 // Fix a call site by handing return type changes and/or parameter type and
439 // attribute changes.
440 template <class TCall>
441 void SimplifyStructRegSignatures::fixCallSite(LLVMContext &Ctx, TCall *OldCall,
442 unsigned PreferredAlignment) {
443 Value *NewTarget = OldCall->getCalledValue();
444
445 if (Function *CalledFunc = dyn_cast<Function>(NewTarget)) {
446 NewTarget = this->FunctionMap[CalledFunc];
447 }
448 assert(NewTarget);
449
450 auto *NewType = cast<FunctionType>(
451 Mapper.getSimpleType(Ctx, NewTarget->getType())->getPointerElementType());
452
453 auto *OldRetType = OldCall->getType();
454 const bool IsSRet =
455 !OldCall->getType()->isVoidTy() && NewType->getReturnType()->isVoidTy();
456
457 IRBuilder<> Builder(OldCall);
458 auto AllocaInsPoint =
459 OldCall->getParent()->getParent()->getEntryBlock().getFirstInsertionPt();
460
461 if (IsSRet) {
462 auto *Alloca = InsertAllocaAtLocation(Builder, AllocaInsPoint, OldRetType);
463
464 Alloca->takeName(OldCall);
465 Alloca->setAlignment(PreferredAlignment);
466
467 auto *NewCall = fixCallTargetAndArguments(Ctx, Builder, OldCall, NewTarget,
468 NewType, AllocaInsPoint, Alloca);
469 assert(NewCall);
470 if (auto *Invoke = dyn_cast<InvokeInst>(OldCall))
471 Builder.SetInsertPoint(Invoke->getNormalDest()->getFirstInsertionPt());
472
473 auto *Load = Builder.CreateLoad(Alloca, Alloca->getName() + ".sreg");
474 Load->setAlignment(Alloca->getAlignment());
475 OldCall->replaceAllUsesWith(Load);
476 } else {
477 auto *NewCall = fixCallTargetAndArguments(Ctx, Builder, OldCall, NewTarget,
478 NewType, AllocaInsPoint);
479 OldCall->replaceAllUsesWith(NewCall);
480 }
481
482 OldCall->eraseFromParent();
483 }
484
485 template <class TCall>
486 TCall *SimplifyStructRegSignatures::fixCallTargetAndArguments(
487 LLVMContext &Ctx, IRBuilder<> &Builder, TCall *OldCall, Value *NewTarget,
488 FunctionType *NewType, BasicBlock::iterator AllocaInsPoint,
489 Value *ExtraArg) {
490 SmallSetVector<unsigned, TypicalFuncArity> ByRefPlaces;
491 SmallVector<Value *, TypicalFuncArity> NewArgs;
492
493 unsigned argOffset = ExtraArg ? 1 : 0;
494 if (ExtraArg)
495 NewArgs.push_back(ExtraArg);
496
497 // Go over the argument list used in the call/invoke, in order to
498 // correctly deal with varargs scenarios.
499 unsigned NumActualParams = OldCall->getNumArgOperands();
500 unsigned VarargMark = NewType->getNumParams();
501 for (unsigned ArgPos = 0; ArgPos < NumActualParams; ArgPos++) {
502
503 Use &OldArgUse = OldCall->getOperandUse(ArgPos);
504 Value *OldArg = OldArgUse;
505 Type *OldArgType = OldArg->getType();
506 unsigned NewArgPos = OldArgUse.getOperandNo() + argOffset;
507 Type *NewArgType = NewType->getFunctionParamType(NewArgPos);
508
509 if (OldArgType != NewArgType && OldArgType->isAggregateType()) {
510 if (NewArgPos >= VarargMark) {
511 errs() << *OldCall << '\n';
512 report_fatal_error("Aggregate register vararg is not supported");
513 }
514 auto *Alloca =
515 InsertAllocaAtLocation(Builder, AllocaInsPoint, OldArgType);
516 Alloca->setName(OldArg->getName() + ".ptr");
517
518 Builder.CreateStore(OldArg, Alloca);
519 ByRefPlaces.insert(NewArgPos);
520 NewArgs.push_back(Alloca);
521 } else {
522 NewArgs.push_back(OldArg);
523 }
524 }
525
526 ArrayRef<Value *> ArrRef = NewArgs;
527 TCall *NewCall = CreateCallFrom(OldCall, NewTarget, ArrRef, Builder);
528
529 // Copy the attributes over, and add byref/sret as necessary.
530 const AttributeSet &OldAttrSet = OldCall->getAttributes();
531 const AttributeSet &NewAttrSet = NewCall->getAttributes();
532
533 for (unsigned I = 0; I < NewCall->getNumArgOperands(); I++) {
534 NewCall->setAttributes(NewAttrSet.addAttributes(
535 Ctx, I + argOffset + 1, OldAttrSet.getParamAttributes(I + 1)));
536 if (ByRefPlaces.count(I)) {
537 NewCall->addAttribute(I + 1, Attribute::ByVal);
538 }
539 }
540
541 if (ExtraArg) {
542 NewAttrSet.addAttributes(Ctx, 1, OldAttrSet.getRetAttributes());
543 NewCall->addAttribute(1, Attribute::StructRet);
544 } else {
545 NewCall->setAttributes(NewAttrSet.addAttributes(
546 Ctx, AttributeSet::ReturnIndex, OldAttrSet.getRetAttributes()));
547 }
548 return NewCall;
549 }
550
551 void SimplifyStructRegSignatures::scheduleInstructionsForCleanup(
552 Function *NewFunc) {
553 for (auto &BBIter : NewFunc->getBasicBlockList()) {
554 for (auto &IIter : BBIter.getInstList()) {
555 if (CallInst *Call = dyn_cast<CallInst>(&IIter)) {
556 CallsToPatch.insert(Call);
557 } else if (InvokeInst *Invoke = dyn_cast<InvokeInst>(&IIter)) {
558 InvokesToPatch.insert(Invoke);
559 }
560 }
561 }
562 }
563
564 // Change function body in the light of type changes.
565 void SimplifyStructRegSignatures::fixFunctionBody(LLVMContext &Ctx,
566 Function *OldFunc,
567 Function *NewFunc) {
568 if (NewFunc->empty())
569 return;
570
571 bool returnWasFixed = OldFunc->getReturnType()->isAggregateType();
572
573 Instruction *InsPoint = NewFunc->begin()->begin();
574 auto NewArgIter = NewFunc->arg_begin();
575 // Advance one more if we used to return a struct register.
576 if (returnWasFixed)
577 NewArgIter++;
578
579 // Wire new parameters in.
580 for (auto ArgIter = OldFunc->arg_begin(), E = OldFunc->arg_end();
581 E != ArgIter;) {
582 Argument *OldArg = ArgIter++;
583 Argument *NewArg = NewArgIter++;
584 ConvertArgumentValue(OldArg, NewArg, InsPoint);
585 }
586
587 // Now fix instruction types. We know that each value could only possibly be
588 // of a simplified type. At the end of this, call sites will be invalid, but
589 // we handle that afterwards, to make sure we have all the functions changed
590 // first (so that calls have valid targets)
591 for (auto BBIter = NewFunc->begin(), LBlock = NewFunc->end();
592 LBlock != BBIter;) {
593 auto Block = BBIter++;
594 for (auto IIter = Block->begin(), LIns = Block->end(); LIns != IIter;) {
595 auto Instr = IIter++;
596 Instr->mutateType(Mapper.getSimpleType(Ctx, Instr->getType()));
597 }
598 }
599 if (returnWasFixed)
600 FixReturn(OldFunc, NewFunc);
601 }
602
603 // Ensure function is simplified, returning true if the function
604 // had to be changed.
605 bool SimplifyStructRegSignatures::simplifyFunction(
606 LLVMContext &Ctx, Function *OldFunc,
607 DenseMap<const Function *, DISubprogram> &DISubprogramMap) {
608 auto *OldFT = OldFunc->getFunctionType();
609 auto *NewFT = cast<FunctionType>(Mapper.getSimpleType(Ctx, OldFT));
610
611 Function *&AssociatedFctLoc = FunctionMap[OldFunc];
612 if (NewFT != OldFT) {
613 auto *NewFunc = Function::Create(NewFT, OldFunc->getLinkage());
614 AssociatedFctLoc = NewFunc;
615
616 NewFunc->copyAttributesFrom(OldFunc);
617 OldFunc->getParent()->getFunctionList().insert(OldFunc, NewFunc);
618 NewFunc->takeName(OldFunc);
619
620 UpdateArgNames(OldFunc, NewFunc);
621 ApplyByValAndSRet(OldFunc, NewFunc);
622
623 NewFunc->getBasicBlockList().splice(NewFunc->begin(),
624 OldFunc->getBasicBlockList());
625
626 fixFunctionBody(Ctx, OldFunc, NewFunc);
627 FunctionsToDelete.insert(OldFunc);
628 auto Found = DISubprogramMap.find(OldFunc);
629 if (Found != DISubprogramMap.end())
630 Found->second.replaceFunction(NewFunc);
631 } else {
632 AssociatedFctLoc = OldFunc;
633 }
634 scheduleInstructionsForCleanup(AssociatedFctLoc);
635 return NewFT != OldFT;
636 }
637
638 bool SimplifyStructRegSignatures::runOnModule(Module &M) {
639 bool Changed = false;
640
641 const DataLayout *DL = M.getDataLayout();
642 unsigned PreferredAlignment = 0;
643 if (DL)
644 PreferredAlignment = DL->getStackAlignment();
645
646 LLVMContext &Ctx = M.getContext();
647 auto DISubprogramMap = makeSubprogramMap(M);
648
649 // Change function signatures and fix a changed function body by
650 // wiring the new arguments. Call sites are unchanged at this point.
651 for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E;) {
652 Function *Func = Iter++;
653 checkNoUnsupportedInstructions(Ctx, Func);
654 Changed |= simplifyFunction(Ctx, Func, DISubprogramMap);
655 }
656
657 // Fix call sites.
658 for (auto &CallToFix : CallsToPatch) {
659 fixCallSite(Ctx, CallToFix, PreferredAlignment);
660 }
661
662 for (auto &InvokeToFix : InvokesToPatch) {
663 fixCallSite(Ctx, InvokeToFix, PreferredAlignment);
664 }
665
666 // Delete leftover functions - the ones with old signatures.
667 for (auto &ToDelete : FunctionsToDelete) {
668 ToDelete->eraseFromParent();
669 }
670
671 return Changed;
672 }
673
674 void SimplifyStructRegSignatures::checkNoUnsupportedInstructions(
675 LLVMContext &Ctx, Function *Fct) {
676 for (auto &BB : Fct->getBasicBlockList())
677 for (auto &Inst : BB.getInstList())
678 if (auto *Landing = dyn_cast<LandingPadInst>(&Inst)) {
679 auto *LType = Landing->getPersonalityFn()->getType();
680 if (LType != Mapper.getSimpleType(Ctx, LType)) {
681 errs() << *Landing << '\n';
682 report_fatal_error("Landing pads with aggregate register "
683 "signatures are not supported.");
684 }
685 } else if (auto *Resume = dyn_cast<ResumeInst>(&Inst)) {
686 auto *RType = Resume->getValue()->getType();
687 if (RType != Mapper.getSimpleType(Ctx, RType)) {
688 errs() << *Resume << '\n';
689 report_fatal_error(
690 "Resumes with aggregate register signatures are not supported.");
691 }
692 }
693 }
694
695 ModulePass *llvm::createSimplifyStructRegSignaturesPass() {
696 return new SimplifyStructRegSignatures();
697 }
OLDNEW
« no previous file with comments | « lib/Transforms/NaCl/PNaClABISimplify.cpp ('k') | test/Transforms/NaCl/simplify-struct-reg-pad-crash.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698