mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-26 12:20:42 +00:00
[XCore] Move lowering of thread local storage to a separate pass.
Thread local storage is not supported by the XMOS linker so we handle thread local variables by lowering the variable to an array of n elements (where n is the number of hardware threads per core, currently 8 for all XMOS devices) indexed by the the current thread ID. Previously this lowering was spread across the XCoreISelLowering and the XCoreAsmPrinter classes. Moving this to a separate pass should be much cleaner. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181124 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -120,9 +120,6 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
setOperationAction(ISD::BlockAddress, MVT::i32 , Custom);
|
||||
|
||||
// Thread Local Storage
|
||||
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
|
||||
|
||||
// Conversion of i64 -> double produces constantpool nodes
|
||||
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
|
||||
|
||||
@@ -172,7 +169,6 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
switch (Op.getOpcode())
|
||||
{
|
||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
|
||||
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
|
||||
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
|
||||
case ISD::BR_JT: return LowerBR_JT(Op, DAG);
|
||||
@@ -255,44 +251,6 @@ static inline SDValue BuildGetId(SelectionDAG &DAG, DebugLoc dl) {
|
||||
DAG.getConstant(Intrinsic::xcore_getid, MVT::i32));
|
||||
}
|
||||
|
||||
static inline bool isZeroLengthArray(Type *Ty) {
|
||||
ArrayType *AT = dyn_cast_or_null<ArrayType>(Ty);
|
||||
return AT && (AT->getNumElements() == 0);
|
||||
}
|
||||
|
||||
SDValue XCoreTargetLowering::
|
||||
LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
|
||||
{
|
||||
// FIXME there isn't really debug info here
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
// transform to label + getid() * size
|
||||
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32);
|
||||
const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
|
||||
if (!GVar) {
|
||||
// If GV is an alias then use the aliasee to determine size
|
||||
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
|
||||
GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal());
|
||||
}
|
||||
if (!GVar) {
|
||||
llvm_unreachable("Thread local object not a GlobalVariable?");
|
||||
}
|
||||
Type *Ty = cast<PointerType>(GV->getType())->getElementType();
|
||||
if (!Ty->isSized() || isZeroLengthArray(Ty)) {
|
||||
#ifndef NDEBUG
|
||||
errs() << "Size of thread local object " << GVar->getName()
|
||||
<< " is unknown\n";
|
||||
#endif
|
||||
llvm_unreachable(0);
|
||||
}
|
||||
SDValue base = getGlobalAddressWrapper(GA, GV, DAG);
|
||||
const DataLayout *TD = TM.getDataLayout();
|
||||
unsigned Size = TD->getTypeAllocSize(Ty);
|
||||
SDValue offset = DAG.getNode(ISD::MUL, dl, MVT::i32, BuildGetId(DAG, dl),
|
||||
DAG.getConstant(Size, MVT::i32));
|
||||
return DAG.getNode(ISD::ADD, dl, MVT::i32, base, offset);
|
||||
}
|
||||
|
||||
SDValue XCoreTargetLowering::
|
||||
LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user