mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-27 14:24:40 +00:00
Just because a GlobalVariable's initializer is [N x { i32, void ()* }] doesn't
mean that it has to be ConstantArray of ConstantStruct. We might have ConstantAggregateZero, at either level, so don't crash on that. Also, semi-deprecate the sentinal value. The linker isn't aware of sentinals so we end up with the two lists appended, each with their "sentinals" on them. Different parts of LLVM treated sentinals differently, so make them all just ignore the single entry and continue on with the rest of the list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129307 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -662,12 +662,16 @@ bool ELFWriter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
|
|||||||
void ELFWriter::EmitXXStructorList(Constant *List, ELFSection &Xtor) {
|
void ELFWriter::EmitXXStructorList(Constant *List, ELFSection &Xtor) {
|
||||||
// Should be an array of '{ i32, void ()* }' structs. The first value is the
|
// Should be an array of '{ i32, void ()* }' structs. The first value is the
|
||||||
// init priority, which we ignore.
|
// init priority, which we ignore.
|
||||||
|
if (List->isNullValue()) return;
|
||||||
ConstantArray *InitList = cast<ConstantArray>(List);
|
ConstantArray *InitList = cast<ConstantArray>(List);
|
||||||
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
|
||||||
|
if (InitList->getOperand(i)->isNullValue())
|
||||||
|
continue;
|
||||||
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(i));
|
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(i));
|
||||||
|
|
||||||
if (CS->getOperand(1)->isNullValue())
|
if (CS->getOperand(1)->isNullValue())
|
||||||
return; // Found a null terminator, exit printing.
|
continue;
|
||||||
|
|
||||||
// Emit the function pointer.
|
// Emit the function pointer.
|
||||||
EmitGlobalConstant(CS->getOperand(1), Xtor);
|
EmitGlobalConstant(CS->getOperand(1), Xtor);
|
||||||
}
|
}
|
||||||
|
@ -313,13 +313,17 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module,
|
|||||||
|
|
||||||
// Should be an array of '{ i32, void ()* }' structs. The first value is
|
// Should be an array of '{ i32, void ()* }' structs. The first value is
|
||||||
// the init priority, which we ignore.
|
// the init priority, which we ignore.
|
||||||
|
if (isa<ConstantAggregateZero>(GV->getInitializer()))
|
||||||
|
return;
|
||||||
ConstantArray *InitList = cast<ConstantArray>(GV->getInitializer());
|
ConstantArray *InitList = cast<ConstantArray>(GV->getInitializer());
|
||||||
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
|
||||||
|
if (isa<ConstantAggregateZero>(InitList->getOperand(i)))
|
||||||
|
continue;
|
||||||
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(i));
|
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(i));
|
||||||
|
|
||||||
Constant *FP = CS->getOperand(1);
|
Constant *FP = CS->getOperand(1);
|
||||||
if (FP->isNullValue())
|
if (FP->isNullValue())
|
||||||
break; // Found a null terminator, exit.
|
continue; // Found a sentinal value, ignore.
|
||||||
|
|
||||||
// Strip off constant expression casts.
|
// Strip off constant expression casts.
|
||||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
|
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
|
||||||
|
@ -1955,13 +1955,14 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
|
|||||||
// only allowed to optimize the initializer if it is unique.
|
// only allowed to optimize the initializer if it is unique.
|
||||||
if (!GV->hasUniqueInitializer()) return 0;
|
if (!GV->hasUniqueInitializer()) return 0;
|
||||||
|
|
||||||
ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer());
|
if (isa<ConstantAggregateZero>(GV->getInitializer()))
|
||||||
if (!CA) return 0;
|
return GV;
|
||||||
|
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
|
||||||
|
|
||||||
for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) {
|
for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) {
|
||||||
ConstantStruct *CS = dyn_cast<ConstantStruct>(*i);
|
if (isa<ConstantAggregateZero>(*i))
|
||||||
if (!CS) return 0;
|
continue;
|
||||||
|
ConstantStruct *CS = cast<ConstantStruct>(*i);
|
||||||
if (isa<ConstantPointerNull>(CS->getOperand(1)))
|
if (isa<ConstantPointerNull>(CS->getOperand(1)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1981,6 +1982,8 @@ GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
|
|||||||
/// ParseGlobalCtors - Given a llvm.global_ctors list that we can understand,
|
/// ParseGlobalCtors - Given a llvm.global_ctors list that we can understand,
|
||||||
/// return a list of the functions and null terminator as a vector.
|
/// return a list of the functions and null terminator as a vector.
|
||||||
static std::vector<Function*> ParseGlobalCtors(GlobalVariable *GV) {
|
static std::vector<Function*> ParseGlobalCtors(GlobalVariable *GV) {
|
||||||
|
if (GV->getInitializer()->isNullValue())
|
||||||
|
return std::vector<Function*>();
|
||||||
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
|
ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
|
||||||
std::vector<Function*> Result;
|
std::vector<Function*> Result;
|
||||||
Result.reserve(CA->getNumOperands());
|
Result.reserve(CA->getNumOperands());
|
||||||
@ -2011,7 +2014,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
|
|||||||
const PointerType *PFTy = PointerType::getUnqual(FTy);
|
const PointerType *PFTy = PointerType::getUnqual(FTy);
|
||||||
CSVals[1] = Constant::getNullValue(PFTy);
|
CSVals[1] = Constant::getNullValue(PFTy);
|
||||||
CSVals[0] = ConstantInt::get(Type::getInt32Ty(GCL->getContext()),
|
CSVals[0] = ConstantInt::get(Type::getInt32Ty(GCL->getContext()),
|
||||||
2147483647);
|
0x7fffffff);
|
||||||
}
|
}
|
||||||
CAList.push_back(ConstantStruct::get(GCL->getContext(), CSVals, false));
|
CAList.push_back(ConstantStruct::get(GCL->getContext(), CSVals, false));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user