mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 23:32:27 +00:00
Add transformations for Load and GetElementPtr. Fix broken transform with shr.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1118 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ab9f21f4c4
commit
b96939519b
@ -221,8 +221,48 @@ static bool ExpressionConvertableToType(Value *V, const Type *Ty) {
|
|||||||
return ExpressionConvertableToType(I->getOperand(0), Ty) &&
|
return ExpressionConvertableToType(I->getOperand(0), Ty) &&
|
||||||
ExpressionConvertableToType(I->getOperand(1), Ty);
|
ExpressionConvertableToType(I->getOperand(1), Ty);
|
||||||
case Instruction::Shl:
|
case Instruction::Shl:
|
||||||
case Instruction::Shr:
|
|
||||||
return ExpressionConvertableToType(I->getOperand(0), Ty);
|
return ExpressionConvertableToType(I->getOperand(0), Ty);
|
||||||
|
case Instruction::Shr:
|
||||||
|
if (Ty->isSigned() != V->getType()->isSigned()) return false;
|
||||||
|
return ExpressionConvertableToType(I->getOperand(0), Ty);
|
||||||
|
|
||||||
|
case Instruction::Load: {
|
||||||
|
LoadInst *LI = cast<LoadInst>(I);
|
||||||
|
if (LI->hasIndices()) return false;
|
||||||
|
return ExpressionConvertableToType(LI->getPtrOperand(),
|
||||||
|
PointerType::get(Ty));
|
||||||
|
}
|
||||||
|
case Instruction::GetElementPtr: {
|
||||||
|
// GetElementPtr's are directly convertable to a pointer type if they have
|
||||||
|
// a number of zeros at the end. Because removing these values does not
|
||||||
|
// change the logical offset of the GEP, it is okay and fair to remove them.
|
||||||
|
// This can change this:
|
||||||
|
// %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0 ; <%List **>
|
||||||
|
// %t2 = cast %List * * %t1 to %List *
|
||||||
|
// into
|
||||||
|
// %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
|
||||||
|
//
|
||||||
|
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
|
||||||
|
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
||||||
|
if (!PTy) return false;
|
||||||
|
|
||||||
|
// Check to see if there are zero elements that we can remove from the
|
||||||
|
// index array. If there are, check to see if removing them causes us to
|
||||||
|
// get to the right type...
|
||||||
|
//
|
||||||
|
vector<ConstPoolVal*> Indices = GEP->getIndexVec();
|
||||||
|
const Type *BaseType = GEP->getPtrOperand()->getType();
|
||||||
|
|
||||||
|
while (Indices.size() &&
|
||||||
|
cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
|
||||||
|
Indices.pop_back();
|
||||||
|
const Type *ElTy = GetElementPtrInst::getIndexedType(BaseType, Indices,
|
||||||
|
true);
|
||||||
|
if (ElTy == PTy->getValueType())
|
||||||
|
return true; // Found a match!!
|
||||||
|
}
|
||||||
|
break; // No match, maybe next time.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -269,6 +309,50 @@ static Value *ConvertExpressionToType(Value *V, const Type *Ty) {
|
|||||||
I->getOperand(1), Name);
|
I->getOperand(1), Name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Instruction::Load: {
|
||||||
|
LoadInst *LI = cast<LoadInst>(I);
|
||||||
|
assert(!LI->hasIndices());
|
||||||
|
Res = new LoadInst(ConvertExpressionToType(LI->getPtrOperand(),
|
||||||
|
PointerType::get(Ty)), Name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Instruction::GetElementPtr: {
|
||||||
|
// GetElementPtr's are directly convertable to a pointer type if they have
|
||||||
|
// a number of zeros at the end. Because removing these values does not
|
||||||
|
// change the logical offset of the GEP, it is okay and fair to remove them.
|
||||||
|
// This can change this:
|
||||||
|
// %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0 ; <%List **>
|
||||||
|
// %t2 = cast %List * * %t1 to %List *
|
||||||
|
// into
|
||||||
|
// %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
|
||||||
|
//
|
||||||
|
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
|
||||||
|
|
||||||
|
// Check to see if there are zero elements that we can remove from the
|
||||||
|
// index array. If there are, check to see if removing them causes us to
|
||||||
|
// get to the right type...
|
||||||
|
//
|
||||||
|
vector<ConstPoolVal*> Indices = GEP->getIndexVec();
|
||||||
|
const Type *BaseType = GEP->getPtrOperand()->getType();
|
||||||
|
const Type *PVTy = cast<PointerType>(Ty)->getValueType();
|
||||||
|
Res = 0;
|
||||||
|
while (Indices.size() &&
|
||||||
|
cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
|
||||||
|
Indices.pop_back();
|
||||||
|
if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) {
|
||||||
|
if (Indices.size() == 0) {
|
||||||
|
Res = new CastInst(GEP->getPtrOperand(), BaseType); // NOOP
|
||||||
|
} else {
|
||||||
|
Res = new GetElementPtrInst(GEP->getPtrOperand(), Indices, Name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(Res && "Didn't find match!");
|
||||||
|
break; // No match, maybe next time.
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "Expression convertable, but don't know how to convert?");
|
assert(0 && "Expression convertable, but don't know how to convert?");
|
||||||
return 0;
|
return 0;
|
||||||
@ -458,6 +542,18 @@ static bool PeepholeMallocInst(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Peephole optimize the following instructions:
|
||||||
|
// %t1 = cast int (uint) * %reg111 to uint (...) *
|
||||||
|
// %t2 = call uint (...) * %cast111( uint %key )
|
||||||
|
//
|
||||||
|
// Into: %t3 = call int (uint) * %reg111( uint %key )
|
||||||
|
// %t2 = cast int %t3 to uint
|
||||||
|
//
|
||||||
|
static bool PeepholeCallInst(BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||||
|
CallInst *CI = cast<CallInst>(*BI);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
||||||
Instruction *I = *BI;
|
Instruction *I = *BI;
|
||||||
@ -596,6 +692,9 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
|
|||||||
} else if (MallocInst *MI = dyn_cast<MallocInst>(I)) {
|
} else if (MallocInst *MI = dyn_cast<MallocInst>(I)) {
|
||||||
if (PeepholeMallocInst(BB, BI)) return true;
|
if (PeepholeMallocInst(BB, BI)) return true;
|
||||||
|
|
||||||
|
} else if (CallInst *CI = dyn_cast<CallInst>(I)) {
|
||||||
|
if (PeepholeCallInst(BB, BI)) return true;
|
||||||
|
|
||||||
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
||||||
Value *Val = SI->getOperand(0);
|
Value *Val = SI->getOperand(0);
|
||||||
Value *Pointer = SI->getPtrOperand();
|
Value *Pointer = SI->getPtrOperand();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user