mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-05-30 05:35:59 +02:00
Metadata/gc2stack compile fixes to accomodate LLVM API changes.
This commit is contained in:
@@ -20,15 +20,6 @@
|
|||||||
#include "llvm/Metadata.h"
|
#include "llvm/Metadata.h"
|
||||||
typedef llvm::Value MDNodeField;
|
typedef llvm::Value MDNodeField;
|
||||||
|
|
||||||
// Use getNumElements() and getElement() to access elements.
|
|
||||||
inline unsigned MD_GetNumElements(llvm::MDNode* N) {
|
|
||||||
return N->getNumElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline MDNodeField* MD_GetElement(llvm::MDNode* N, unsigned i) {
|
|
||||||
return N->getElement(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define METADATA_LINKAGE_TYPE llvm::GlobalValue::WeakODRLinkage
|
#define METADATA_LINKAGE_TYPE llvm::GlobalValue::WeakODRLinkage
|
||||||
|
|
||||||
// *** Metadata for TypeInfo instances ***
|
// *** Metadata for TypeInfo instances ***
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "gen/runtime.h"
|
||||||
#include "gen/metadata.h"
|
#include "gen/metadata.h"
|
||||||
|
|
||||||
#define DEBUG_TYPE "dgc2stack"
|
#define DEBUG_TYPE "dgc2stack"
|
||||||
@@ -53,7 +54,7 @@ namespace {
|
|||||||
CallGraph* CG;
|
CallGraph* CG;
|
||||||
CallGraphNode* CGNode;
|
CallGraphNode* CGNode;
|
||||||
|
|
||||||
const Type* getTypeFor(Value* typeinfo) const;
|
Type* getTypeFor(Value* typeinfo) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,10 +67,11 @@ void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len,
|
|||||||
Dst = B.CreateBitCast(Dst, PointerType::getUnqual(B.getInt8Ty()));
|
Dst = B.CreateBitCast(Dst, PointerType::getUnqual(B.getInt8Ty()));
|
||||||
|
|
||||||
Module *M = B.GetInsertBlock()->getParent()->getParent();
|
Module *M = B.GetInsertBlock()->getParent()->getParent();
|
||||||
const Type* intTy = Len->getType();
|
Type* intTy = Len->getType();
|
||||||
const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
|
Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
|
||||||
const Type *Tys[2] ={VoidPtrTy, intTy};
|
Type *Tys[2] = {VoidPtrTy, intTy};
|
||||||
Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2);
|
Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset,
|
||||||
|
llvm::makeArrayRef(Tys, 2));
|
||||||
Value *Align = ConstantInt::get(B.getInt32Ty(), 1);
|
Value *Align = ConstantInt::get(B.getInt32Ty(), 1);
|
||||||
|
|
||||||
CallSite CS = B.CreateCall5(MemSet, Dst, Val, Len, Align, B.getFalse());
|
CallSite CS = B.CreateCall5(MemSet, Dst, Val, Len, Align, B.getFalse());
|
||||||
@@ -90,7 +92,7 @@ static void EmitMemZero(IRBuilder<>& B, Value* Dst, Value* Len,
|
|||||||
namespace {
|
namespace {
|
||||||
class FunctionInfo {
|
class FunctionInfo {
|
||||||
protected:
|
protected:
|
||||||
const Type* Ty;
|
Type* Ty;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned TypeInfoArgNr;
|
unsigned TypeInfoArgNr;
|
||||||
@@ -145,7 +147,11 @@ namespace {
|
|||||||
// the conversion is safe.
|
// the conversion is safe.
|
||||||
APInt Mask = APInt::getHighBitsSet(bits, bits - 32);
|
APInt Mask = APInt::getHighBitsSet(bits, bits - 32);
|
||||||
APInt KnownZero(bits, 0), KnownOne(bits, 0);
|
APInt KnownZero(bits, 0), KnownOne(bits, 0);
|
||||||
|
#if LDC_LLVM_VER >= 301
|
||||||
|
ComputeMaskedBits(arrSize, KnownZero, KnownOne, &A.TD);
|
||||||
|
#else
|
||||||
ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &A.TD);
|
ComputeMaskedBits(arrSize, Mask, KnownZero, KnownOne, &A.TD);
|
||||||
|
#endif
|
||||||
if ((KnownZero & Mask) != Mask)
|
if ((KnownZero & Mask) != Mask)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -213,17 +219,17 @@ namespace {
|
|||||||
if (!meta)
|
if (!meta)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MDNode* node = static_cast<MDNode*>(meta->getElement(0));
|
MDNode* node = static_cast<MDNode*>(meta->getOperand(0));
|
||||||
if (!node || MD_GetNumElements(node) != CD_NumFields)
|
if (!node || node->getNumOperands() != CD_NumFields)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Inserting destructor calls is not implemented yet, so classes
|
// Inserting destructor calls is not implemented yet, so classes
|
||||||
// with destructors are ignored for now.
|
// with destructors are ignored for now.
|
||||||
Constant* hasDestructor = dyn_cast<Constant>(MD_GetElement(node, CD_Finalize));
|
Constant* hasDestructor = dyn_cast<Constant>(node->getOperand(CD_Finalize));
|
||||||
// We can't stack-allocate if the class has a custom deallocator
|
// We can't stack-allocate if the class has a custom deallocator
|
||||||
// (Custom allocators don't get turned into this runtime call, so
|
// (Custom allocators don't get turned into this runtime call, so
|
||||||
// those can be ignored)
|
// those can be ignored)
|
||||||
Constant* hasCustomDelete = dyn_cast<Constant>(MD_GetElement(node, CD_CustomDelete));
|
Constant* hasCustomDelete = dyn_cast<Constant>(node->getOperand(CD_CustomDelete));
|
||||||
if (hasDestructor == NULL || hasCustomDelete == NULL)
|
if (hasDestructor == NULL || hasCustomDelete == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -231,7 +237,7 @@ namespace {
|
|||||||
!= ConstantInt::getFalse(A.M.getContext()))
|
!= ConstantInt::getFalse(A.M.getContext()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Ty = MD_GetElement(node, CD_BodyType)->getType();
|
Ty =node->getOperand(CD_BodyType)->getType();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +295,7 @@ FunctionPass *createGarbageCollect2Stack() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GarbageCollect2Stack::GarbageCollect2Stack()
|
GarbageCollect2Stack::GarbageCollect2Stack()
|
||||||
: FunctionPass(&ID),
|
: FunctionPass(ID),
|
||||||
AllocMemoryT(0, true),
|
AllocMemoryT(0, true),
|
||||||
NewArrayVT(0, true, false, 1),
|
NewArrayVT(0, true, false, 1),
|
||||||
NewArrayT(0, true, true, 1)
|
NewArrayT(0, true, true, 1)
|
||||||
@@ -340,7 +346,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) {
|
|||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
|
||||||
// Ignore non-calls.
|
// Ignore non-calls.
|
||||||
Instruction* Inst = I++;
|
Instruction* Inst = I++;
|
||||||
CallSite CS = CallSite::get(Inst);
|
CallSite CS(Inst);
|
||||||
if (!CS.getInstruction())
|
if (!CS.getInstruction())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -393,7 +399,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) {
|
|||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type* Analysis::getTypeFor(Value* typeinfo) const {
|
Type* Analysis::getTypeFor(Value* typeinfo) const {
|
||||||
GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
|
GlobalVariable* ti_global = dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
|
||||||
if (!ti_global)
|
if (!ti_global)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -405,17 +411,17 @@ const Type* Analysis::getTypeFor(Value* typeinfo) const {
|
|||||||
if (!meta)
|
if (!meta)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
MDNode* node = static_cast<MDNode*>(meta->getElement(0));
|
MDNode* node = static_cast<MDNode*>(meta->getOperand(0));
|
||||||
if (!node)
|
if (!node)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (MD_GetNumElements(node) != TD_NumFields)
|
if (node->getNumOperands() != TD_NumFields)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (TD_Confirm >= 0 && (!MD_GetElement(node, TD_Confirm) ||
|
if (TD_Confirm >= 0 && (!node->getOperand(TD_Confirm) ||
|
||||||
MD_GetElement(node, TD_Confirm)->stripPointerCasts() != ti_global))
|
node->getOperand(TD_Confirm)->stripPointerCasts() != ti_global))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return MD_GetElement(node, TD_Type)->getType();
|
return node->getOperand(TD_Type)->getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether Def is used by any instruction that is reachable from Alloc
|
/// Returns whether Def is used by any instruction that is reachable from Alloc
|
||||||
@@ -584,7 +590,7 @@ bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) {
|
|||||||
switch (I->getOpcode()) {
|
switch (I->getOpcode()) {
|
||||||
case Instruction::Call:
|
case Instruction::Call:
|
||||||
case Instruction::Invoke: {
|
case Instruction::Invoke: {
|
||||||
CallSite CS = CallSite::get(I);
|
CallSite CS(I);
|
||||||
// Not captured if the callee is readonly, doesn't return a copy through
|
// Not captured if the callee is readonly, doesn't return a copy through
|
||||||
// its return value and doesn't unwind (a readonly function can leak bits
|
// its return value and doesn't unwind (a readonly function can leak bits
|
||||||
// by throwing an exception or not depending on the input value).
|
// by throwing an exception or not depending on the input value).
|
||||||
@@ -608,9 +614,6 @@ bool isSafeToStackAllocate(Instruction* Alloc, DominatorTree& DT) {
|
|||||||
// captured.
|
// captured.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Instruction::Free:
|
|
||||||
// Freeing a pointer does not cause it to be captured.
|
|
||||||
break;
|
|
||||||
case Instruction::Load:
|
case Instruction::Load:
|
||||||
// Loading from a pointer does not cause it to be captured.
|
// Loading from a pointer does not cause it to be captured.
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -14,6 +14,13 @@
|
|||||||
#ifndef LDC_GEN_RUNTIME_H_
|
#ifndef LDC_GEN_RUNTIME_H_
|
||||||
#define LDC_GEN_RUNTIME_H_
|
#define LDC_GEN_RUNTIME_H_
|
||||||
|
|
||||||
|
namespace llvm
|
||||||
|
{
|
||||||
|
class Function;
|
||||||
|
class GlobalVariable;
|
||||||
|
class Module;
|
||||||
|
}
|
||||||
|
|
||||||
// D runtime support helpers
|
// D runtime support helpers
|
||||||
|
|
||||||
bool LLVM_D_InitRuntime();
|
bool LLVM_D_InitRuntime();
|
||||||
|
|||||||
@@ -349,10 +349,10 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
|
|||||||
if (TD_Confirm >= 0)
|
if (TD_Confirm >= 0)
|
||||||
mdVals[TD_Confirm] = llvm::cast<MDNodeField>(irg->value);
|
mdVals[TD_Confirm] = llvm::cast<MDNodeField>(irg->value);
|
||||||
mdVals[TD_Type] = llvm::UndefValue::get(DtoType(tid->tinfo));
|
mdVals[TD_Type] = llvm::UndefValue::get(DtoType(tid->tinfo));
|
||||||
// Construct the metadata
|
// Construct the metadata and insert it into the module.
|
||||||
llvm::MetadataBase* metadata = llvm::MDNode::get(gIR->context(), mdVals, TD_NumFields);
|
llvm::NamedMDNode* node = gIR->module->getOrInsertNamedMetadata(metaname);
|
||||||
// Insert it into the module
|
node->addOperand(llvm::MDNode::get(gIR->context(),
|
||||||
llvm::NamedMDNode::Create(gIR->context(), metaname, &metadata, 1, gIR->module);
|
llvm::makeArrayRef(mdVals, TD_NumFields)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_METADATA
|
#endif // USE_METADATA
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
|
||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
#include "declaration.h"
|
#include "declaration.h"
|
||||||
@@ -96,11 +97,12 @@ LLGlobalVariable * IrStruct::getClassInfoSymbol()
|
|||||||
mdVals[CD_BodyType] = llvm::UndefValue::get(bodyType);
|
mdVals[CD_BodyType] = llvm::UndefValue::get(bodyType);
|
||||||
mdVals[CD_Finalize] = LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasDestructor);
|
mdVals[CD_Finalize] = LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasDestructor);
|
||||||
mdVals[CD_CustomDelete] = LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasCustomDelete);
|
mdVals[CD_CustomDelete] = LLConstantInt::get(LLType::getInt1Ty(gIR->context()), hasCustomDelete);
|
||||||
// Construct the metadata
|
// Construct the metadata and insert it into the module.
|
||||||
llvm::MetadataBase* metadata = llvm::MDNode::get(gIR->context(), mdVals, CD_NumFields);
|
llvm::SmallString<64> name;
|
||||||
// Insert it into the module
|
llvm::NamedMDNode* node = gIR->module->getOrInsertNamedMetadata(
|
||||||
std::string metaname = CD_PREFIX + initname;
|
llvm::Twine(CD_PREFIX, initname).toStringRef(name));
|
||||||
llvm::NamedMDNode::Create(gIR->context(), metaname, &metadata, 1, gIR->module);
|
node->addOperand(llvm::MDNode::get(gIR->context(),
|
||||||
|
llvm::makeArrayRef(mdVals, CD_NumFields)));
|
||||||
}
|
}
|
||||||
#endif // USE_METADATA
|
#endif // USE_METADATA
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user