[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:
Sanjoy Das
2015-05-11 18:49:34 +00:00
parent 948b20ecb3
commit 5b5782c20e
12 changed files with 135 additions and 42 deletions

View File

@@ -1075,7 +1075,10 @@ static void CreateGCRelocates(ArrayRef<llvm::Value *> liveVariables,
// the IR, but removes the need for argument bitcasts which shrinks the IR
// greatly and makes it much more readable.
SmallVector<Type *, 1> types; // one per 'any' type
types.push_back(liveVariables[i]->getType()); // result type
// All gc_relocate are set to i8 addrspace(1)* type. This could help avoid
// cases where the actual value's type mangling is not supported by llvm. A
// bitcast is added later to convert gc_relocate to the actual value's type.
types.push_back(Type::getInt8PtrTy(M->getContext(), 1));
Value *gc_relocate_decl = Intrinsic::getDeclaration(
M, Intrinsic::experimental_gc_relocate, types);
@@ -1342,8 +1345,16 @@ insertRelocationStores(iterator_range<Value::user_iterator> gcRelocs,
Value *alloca = allocaMap[originalValue];
// Emit store into the related alloca
StoreInst *store = new StoreInst(relocatedValue, alloca);
store->insertAfter(relocatedValue);
// All gc_relocate are i8 addrspace(1)* typed, and it must be bitcasted to
// the correct type according to alloca.
assert(relocatedValue->getNextNode() && "Should always have one since it's not a terminator");
IRBuilder<> Builder(relocatedValue->getNextNode());
Value *CastedRelocatedValue =
Builder.CreateBitCast(relocatedValue, cast<AllocaInst>(alloca)->getAllocatedType(),
relocatedValue->hasName() ? relocatedValue->getName() + ".casted" : "");
StoreInst *store = new StoreInst(CastedRelocatedValue, alloca);
store->insertAfter(cast<Instruction>(CastedRelocatedValue));
#ifndef NDEBUG
visitedLiveValues.insert(originalValue);