mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-07 12:28:24 +00:00
Fix const merging when an alias of a const is llvm.used.
We used to disable constant merging not only if a constant is llvm.used, but also if an alias of a constant is llvm.used. This change fixes that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181175 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -260,14 +260,24 @@ public:
|
|||||||
/// this value.
|
/// this value.
|
||||||
bool hasValueHandle() const { return HasValueHandle; }
|
bool hasValueHandle() const { return HasValueHandle; }
|
||||||
|
|
||||||
/// stripPointerCasts - This method strips off any unneeded pointer casts and
|
/// \brief This method strips off any unneeded pointer casts,
|
||||||
/// all-zero GEPs from the specified value, returning the original uncasted
|
/// all-zero GEPs and aliases from the specified value, returning the original
|
||||||
/// value. If this is called on a non-pointer value, it returns 'this'.
|
/// uncasted value. If this is called on a non-pointer value, it returns
|
||||||
|
/// 'this'.
|
||||||
Value *stripPointerCasts();
|
Value *stripPointerCasts();
|
||||||
const Value *stripPointerCasts() const {
|
const Value *stripPointerCasts() const {
|
||||||
return const_cast<Value*>(this)->stripPointerCasts();
|
return const_cast<Value*>(this)->stripPointerCasts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief This method strips off any unneeded pointer casts and
|
||||||
|
/// all-zero GEPs from the specified value, returning the original
|
||||||
|
/// uncasted value. If this is called on a non-pointer value, it returns
|
||||||
|
/// 'this'.
|
||||||
|
Value *stripPointerCastsNoFollowAliases();
|
||||||
|
const Value *stripPointerCastsNoFollowAliases() const {
|
||||||
|
return const_cast<Value*>(this)->stripPointerCastsNoFollowAliases();
|
||||||
|
}
|
||||||
|
|
||||||
/// stripInBoundsConstantOffsets - This method strips off unneeded pointer casts and
|
/// stripInBoundsConstantOffsets - This method strips off unneeded pointer casts and
|
||||||
/// all-constant GEPs from the specified value, returning the original
|
/// all-constant GEPs from the specified value, returning the original
|
||||||
/// pointer value. If this is called on a non-pointer value, it returns
|
/// pointer value. If this is called on a non-pointer value, it returns
|
||||||
|
@@ -333,6 +333,7 @@ namespace {
|
|||||||
// Various metrics for how much to strip off of pointers.
|
// Various metrics for how much to strip off of pointers.
|
||||||
enum PointerStripKind {
|
enum PointerStripKind {
|
||||||
PSK_ZeroIndices,
|
PSK_ZeroIndices,
|
||||||
|
PSK_ZeroIndicesAndAliases,
|
||||||
PSK_InBoundsConstantIndices,
|
PSK_InBoundsConstantIndices,
|
||||||
PSK_InBounds
|
PSK_InBounds
|
||||||
};
|
};
|
||||||
@@ -350,6 +351,7 @@ static Value *stripPointerCastsAndOffsets(Value *V) {
|
|||||||
do {
|
do {
|
||||||
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
|
if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
|
||||||
switch (StripKind) {
|
switch (StripKind) {
|
||||||
|
case PSK_ZeroIndicesAndAliases:
|
||||||
case PSK_ZeroIndices:
|
case PSK_ZeroIndices:
|
||||||
if (!GEP->hasAllZeroIndices())
|
if (!GEP->hasAllZeroIndices())
|
||||||
return V;
|
return V;
|
||||||
@@ -367,7 +369,7 @@ static Value *stripPointerCastsAndOffsets(Value *V) {
|
|||||||
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
|
} else if (Operator::getOpcode(V) == Instruction::BitCast) {
|
||||||
V = cast<Operator>(V)->getOperand(0);
|
V = cast<Operator>(V)->getOperand(0);
|
||||||
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
|
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
|
||||||
if (GA->mayBeOverridden())
|
if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden())
|
||||||
return V;
|
return V;
|
||||||
V = GA->getAliasee();
|
V = GA->getAliasee();
|
||||||
} else {
|
} else {
|
||||||
@@ -381,6 +383,10 @@ static Value *stripPointerCastsAndOffsets(Value *V) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Value *Value::stripPointerCasts() {
|
Value *Value::stripPointerCasts() {
|
||||||
|
return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value *Value::stripPointerCastsNoFollowAliases() {
|
||||||
return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
|
return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "llvm/IR/DataLayout.h"
|
#include "llvm/IR/DataLayout.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/Operator.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@@ -68,10 +69,11 @@ static void FindUsedValues(GlobalVariable *LLVMUsed,
|
|||||||
if (LLVMUsed == 0) return;
|
if (LLVMUsed == 0) return;
|
||||||
ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
|
ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
|
||||||
|
|
||||||
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) {
|
||||||
if (GlobalValue *GV =
|
Value *Operand = Inits->getOperand(i)->stripPointerCastsNoFollowAliases();
|
||||||
dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
|
GlobalValue *GV = cast<GlobalValue>(Operand);
|
||||||
UsedValues.insert(GV);
|
UsedValues.insert(GV);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// True if A is better than B.
|
// True if A is better than B.
|
||||||
|
@@ -26,6 +26,9 @@ declare void @helper([16 x i8]*)
|
|||||||
; CHECK-NEXT: @var6 = private constant [16 x i8] c"foo1bar2foo3bar\00", align 16
|
; CHECK-NEXT: @var6 = private constant [16 x i8] c"foo1bar2foo3bar\00", align 16
|
||||||
; CHECK-NEXT: @var8 = private constant [16 x i8] c"foo1bar2foo3bar\00"
|
; CHECK-NEXT: @var8 = private constant [16 x i8] c"foo1bar2foo3bar\00"
|
||||||
|
|
||||||
|
@var4a = alias %struct.foobar* @var4
|
||||||
|
@llvm.used = appending global [1 x %struct.foobar*] [%struct.foobar* @var4a], section "llvm.metadata"
|
||||||
|
|
||||||
define i32 @main() {
|
define i32 @main() {
|
||||||
entry:
|
entry:
|
||||||
call void @zed(%struct.foobar* @var1, %struct.foobar* @var2)
|
call void @zed(%struct.foobar* @var1, %struct.foobar* @var2)
|
||||||
|
Reference in New Issue
Block a user