#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/Support/CallSite.h"
#include "llvm/Support/IRBuilder.h"
using namespace llvm;
namespace {
- class VISIBILITY_HIDDEN ShadowStackGC : public GCStrategy {
+ class ShadowStackGC : public GCStrategy {
/// RootChain - This is the global linked-list that contains the chain of GC
/// roots.
GlobalVariable *Head;
Constant *GetFrameMap(Function &F);
const Type* GetConcreteStackEntryType(Function &F);
void CollectRoots(Function &F);
- static GetElementPtrInst *CreateGEP(LLVMContext *Context,
+ static GetElementPtrInst *CreateGEP(LLVMContext &Context,
IRBuilder<> &B, Value *BasePtr,
int Idx1, const char *Name);
- static GetElementPtrInst *CreateGEP(LLVMContext *Context,
+ static GetElementPtrInst *CreateGEP(LLVMContext &Context,
IRBuilder<> &B, Value *BasePtr,
int Idx1, int Idx2, const char *Name);
};
///
/// It's wrapped up in a state machine using the same transform C# uses for
/// 'yield return' enumerators, This transform allows it to be non-allocating.
- class VISIBILITY_HIDDEN EscapeEnumerator {
+ class EscapeEnumerator {
Function &F;
const char *CleanupBBName;
public:
EscapeEnumerator(Function &F, const char *N = "cleanup")
- : F(F), CleanupBBName(N), State(0), Builder(*F.getContext()) {}
+ : F(F), CleanupBBName(N), State(0), Builder(F.getContext()) {}
IRBuilder<> *Next() {
switch (State) {
return 0;
// Create a cleanup block.
- BasicBlock *CleanupBB = BasicBlock::Create(CleanupBBName, &F);
- UnwindInst *UI = new UnwindInst(CleanupBB);
+ BasicBlock *CleanupBB = BasicBlock::Create(F.getContext(),
+ CleanupBBName, &F);
+ UnwindInst *UI = new UnwindInst(F.getContext(), CleanupBB);
// Transform the 'call' instructions into 'invoke's branching to the
// cleanup block. Go in reverse order to make prettier BB names.
// Create a new invoke instruction.
Args.clear();
- Args.append(CI->op_begin() + 1, CI->op_end());
+ CallSite CS(CI);
+ Args.append(CS.arg_begin(), CS.arg_end());
- InvokeInst *II = InvokeInst::Create(CI->getOperand(0),
+ InvokeInst *II = InvokeInst::Create(CI->getCalledValue(),
NewBB, CleanupBB,
Args.begin(), Args.end(),
CI->getName(), CallBB);
Constant *ShadowStackGC::GetFrameMap(Function &F) {
// doInitialization creates the abstract type of this value.
- LLVMContext *Context = F.getContext();
-
- Type *VoidPtr = PointerType::getUnqual(Type::Int8Ty);
+ const Type *VoidPtr = Type::getInt8PtrTy(F.getContext());
// Truncate the ShadowStackDescriptor if some metadata is null.
unsigned NumMeta = 0;
SmallVector<Constant*,16> Metadata;
for (unsigned I = 0; I != Roots.size(); ++I) {
- Constant *C = cast<Constant>(Roots[I].first->getOperand(2));
+ Constant *C = cast<Constant>(Roots[I].first->getArgOperand(1));
if (!C->isNullValue())
NumMeta = I + 1;
Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr));
}
Constant *BaseElts[] = {
- Context->getConstantInt(Type::Int32Ty, Roots.size(), false),
- Context->getConstantInt(Type::Int32Ty, NumMeta, false),
+ ConstantInt::get(Type::getInt32Ty(F.getContext()), Roots.size(), false),
+ ConstantInt::get(Type::getInt32Ty(F.getContext()), NumMeta, false),
};
Constant *DescriptorElts[] = {
- Context->getConstantStruct(BaseElts, 2),
- Context->getConstantArray(Context->getArrayType(VoidPtr, NumMeta),
+ ConstantStruct::get(F.getContext(), BaseElts, 2, false),
+ ConstantArray::get(ArrayType::get(VoidPtr, NumMeta),
Metadata.begin(), NumMeta)
};
- Constant *FrameMap = Context->getConstantStruct(DescriptorElts, 2);
+ Constant *FrameMap = ConstantStruct::get(F.getContext(), DescriptorElts, 2,
+ false);
std::string TypeName("gc_map.");
TypeName += utostr(NumMeta);
GlobalVariable::InternalLinkage,
FrameMap, "__gc_" + F.getName());
- Constant *GEPIndices[2] = { Context->getConstantInt(Type::Int32Ty, 0),
- Context->getConstantInt(Type::Int32Ty, 0) };
- return Context->getConstantExprGetElementPtr(GV, GEPIndices, 2);
+ Constant *GEPIndices[2] = {
+ ConstantInt::get(Type::getInt32Ty(F.getContext()), 0),
+ ConstantInt::get(Type::getInt32Ty(F.getContext()), 0)
+ };
+ return ConstantExpr::getGetElementPtr(GV, GEPIndices, 2);
}
const Type* ShadowStackGC::GetConcreteStackEntryType(Function &F) {
EltTys.push_back(StackEntryTy);
for (size_t I = 0; I != Roots.size(); I++)
EltTys.push_back(Roots[I].second->getAllocatedType());
- Type *Ty = StructType::get(EltTys);
+ Type *Ty = StructType::get(F.getContext(), EltTys);
std::string TypeName("gc_stackentry.");
TypeName += F.getName();
// void *Meta[]; // May be absent for roots without metadata.
// };
std::vector<const Type*> EltTys;
- EltTys.push_back(Type::Int32Ty); // 32 bits is ok up to a 32GB stack frame. :)
- EltTys.push_back(Type::Int32Ty); // Specifies length of variable length array.
- StructType *FrameMapTy = StructType::get(EltTys);
+ // 32 bits is ok up to a 32GB stack frame. :)
+ EltTys.push_back(Type::getInt32Ty(M.getContext()));
+ // Specifies length of variable length array.
+ EltTys.push_back(Type::getInt32Ty(M.getContext()));
+ StructType *FrameMapTy = StructType::get(M.getContext(), EltTys);
M.addTypeName("gc_map", FrameMapTy);
PointerType *FrameMapPtrTy = PointerType::getUnqual(FrameMapTy);
// FrameMap *Map; // Pointer to constant FrameMap.
// void *Roots[]; // Stack roots (in-place array, so we pretend).
// };
- OpaqueType *RecursiveTy = OpaqueType::get();
+ OpaqueType *RecursiveTy = OpaqueType::get(M.getContext());
EltTys.clear();
EltTys.push_back(PointerType::getUnqual(RecursiveTy));
EltTys.push_back(FrameMapPtrTy);
- PATypeHolder LinkTyH = StructType::get(EltTys);
+ PATypeHolder LinkTyH = StructType::get(M.getContext(), EltTys);
RecursiveTy->refineAbstractTypeTo(LinkTyH.get());
StackEntryTy = cast<StructType>(LinkTyH.get());
// linkage!
Head = new GlobalVariable(M, StackEntryPtrTy, false,
GlobalValue::LinkOnceAnyLinkage,
- M.getContext().getNullValue(StackEntryPtrTy),
+ Constant::getNullValue(StackEntryPtrTy),
"llvm_gc_root_chain");
} else if (Head->hasExternalLinkage() && Head->isDeclaration()) {
- Head->setInitializer(M.getContext().getNullValue(StackEntryPtrTy));
+ Head->setInitializer(Constant::getNullValue(StackEntryPtrTy));
Head->setLinkage(GlobalValue::LinkOnceAnyLinkage);
}
assert(Roots.empty() && "Not cleaned up?");
- SmallVector<std::pair<CallInst*,AllocaInst*>,16> MetaRoots;
+ SmallVector<std::pair<CallInst*, AllocaInst*>, 16> MetaRoots;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;)
if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(II++))
if (Function *F = CI->getCalledFunction())
if (F->getIntrinsicID() == Intrinsic::gcroot) {
- std::pair<CallInst*,AllocaInst*> Pair = std::make_pair(
- CI, cast<AllocaInst>(CI->getOperand(1)->stripPointerCasts()));
- if (IsNullValue(CI->getOperand(2)))
+ std::pair<CallInst*, AllocaInst*> Pair = std::make_pair(
+ CI, cast<AllocaInst>(CI->getArgOperand(0)->stripPointerCasts()));
+ if (IsNullValue(CI->getArgOperand(1)))
Roots.push_back(Pair);
else
MetaRoots.push_back(Pair);
}
GetElementPtrInst *
-ShadowStackGC::CreateGEP(LLVMContext *Context, IRBuilder<> &B, Value *BasePtr,
+ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr,
int Idx, int Idx2, const char *Name) {
- Value *Indices[] = { Context->getConstantInt(Type::Int32Ty, 0),
- Context->getConstantInt(Type::Int32Ty, Idx),
- Context->getConstantInt(Type::Int32Ty, Idx2) };
+ Value *Indices[] = { ConstantInt::get(Type::getInt32Ty(Context), 0),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx2) };
Value* Val = B.CreateGEP(BasePtr, Indices, Indices + 3, Name);
assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant");
}
GetElementPtrInst *
-ShadowStackGC::CreateGEP(LLVMContext *Context, IRBuilder<> &B, Value *BasePtr,
+ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr,
int Idx, const char *Name) {
- Value *Indices[] = { Context->getConstantInt(Type::Int32Ty, 0),
- Context->getConstantInt(Type::Int32Ty, Idx) };
+ Value *Indices[] = { ConstantInt::get(Type::getInt32Ty(Context), 0),
+ ConstantInt::get(Type::getInt32Ty(Context), Idx) };
Value *Val = B.CreateGEP(BasePtr, Indices, Indices + 2, Name);
assert(isa<GetElementPtrInst>(Val) && "Unexpected folded constant");
/// runOnFunction - Insert code to maintain the shadow stack.
bool ShadowStackGC::performCustomLowering(Function &F) {
- LLVMContext *Context = F.getContext();
+ LLVMContext &Context = F.getContext();
// Find calls to llvm.gcroot.
CollectRoots(F);