mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-30 02:25:19 +00:00
[RewriteStatepointsForGC] Fix a bug on creating gc_relocate for pointer to vector of pointers
Summary: In RewriteStatepointsForGC pass, we create a gc_relocate intrinsic for each relocated pointer, and the gc_relocate has the same type with the pointer. During the creation of gc_relocate intrinsic, llvm requires to mangle its type. However, llvm does not support mangling of all possible types. RewriteStatepointsForGC will hit an assertion failure when it tries to create a gc_relocate for pointer to vector of pointers because mangling for vector of pointers is not supported. This patch changes the way RewriteStatepointsForGC pass creates gc_relocate. For each relocated pointer, we erase the type of pointers and create an unified gc_relocate of type i8 addrspace(1)*. Then a bitcast is inserted to convert the gc_relocate to the correct type. In this way, gc_relocate does not need to deal with different types of pointers and the unsupported type mangling is no longer a problem. This change would also ease further merge when LLVM erases types of pointers and introduces an unified pointer type. Some minor changes are also introduced to gc_relocate related part in InstCombineCalls, CodeGenPrepare, and Verifier accordingly. Patch by Chen Li! Reviewers: reames, AndyAyers, sanjoy Reviewed By: sanjoy Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9592 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237009 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -600,13 +600,51 @@ simplifyRelocatesOffABase(IntrinsicInst *RelocatedBase,
|
||||
// Create a Builder and replace the target callsite with a gep
|
||||
IRBuilder<> Builder(ToReplace);
|
||||
Builder.SetCurrentDebugLocation(ToReplace->getDebugLoc());
|
||||
|
||||
// If gc_relocate does not match the actual type, cast it to the right type.
|
||||
// In theory, there must be a bitcast after gc_relocate if the type does not
|
||||
// match, and we should reuse it to get the derived pointer. But it could be
|
||||
// cases like this:
|
||||
// bb1:
|
||||
// ...
|
||||
// %g1 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(...)
|
||||
// br label %merge
|
||||
//
|
||||
// bb2:
|
||||
// ...
|
||||
// %g2 = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(...)
|
||||
// br label %merge
|
||||
//
|
||||
// merge:
|
||||
// %p1 = phi i8 addrspace(1)* [ %g1, %bb1 ], [ %g2, %bb2 ]
|
||||
// %cast = bitcast i8 addrspace(1)* %p1 in to i32 addrspace(1)*
|
||||
//
|
||||
// In this case, we can not find the bitcast any more. So we insert a new bitcast
|
||||
// no matter there is already one or not. In this way, we can handle all cases, and
|
||||
// the extra bitcast should be optimized away in later passes.
|
||||
Instruction *ActualRelocatedBase = RelocatedBase;
|
||||
if (RelocatedBase->getType() != Base->getType()) {
|
||||
ActualRelocatedBase =
|
||||
cast<Instruction>(Builder.CreateBitCast(RelocatedBase, Base->getType()));
|
||||
ActualRelocatedBase->removeFromParent();
|
||||
ActualRelocatedBase->insertAfter(cast<Instruction>(RelocatedBase));
|
||||
}
|
||||
Value *Replacement = Builder.CreateGEP(
|
||||
Derived->getSourceElementType(), RelocatedBase, makeArrayRef(OffsetV));
|
||||
Derived->getSourceElementType(), ActualRelocatedBase, makeArrayRef(OffsetV));
|
||||
Instruction *ReplacementInst = cast<Instruction>(Replacement);
|
||||
ReplacementInst->removeFromParent();
|
||||
ReplacementInst->insertAfter(RelocatedBase);
|
||||
ReplacementInst->insertAfter(ActualRelocatedBase);
|
||||
Replacement->takeName(ToReplace);
|
||||
ToReplace->replaceAllUsesWith(Replacement);
|
||||
// If the newly generated derived pointer's type does not match the original derived
|
||||
// pointer's type, cast the new derived pointer to match it. Same reasoning as above.
|
||||
Instruction *ActualReplacement = ReplacementInst;
|
||||
if (ReplacementInst->getType() != ToReplace->getType()) {
|
||||
ActualReplacement =
|
||||
cast<Instruction>(Builder.CreateBitCast(ReplacementInst, ToReplace->getType()));
|
||||
ActualReplacement->removeFromParent();
|
||||
ActualReplacement->insertAfter(ReplacementInst);
|
||||
}
|
||||
ToReplace->replaceAllUsesWith(ActualReplacement);
|
||||
ToReplace->eraseFromParent();
|
||||
|
||||
MadeChange = true;
|
||||
|
Reference in New Issue
Block a user