mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
Clean up uses of switch instructions so they are not dependent on the operand ordering. Patch by Stepan Dyatkovskiy.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140803 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0066f9290e
commit
bb5a7442e3
@ -2509,6 +2509,13 @@ public:
|
|||||||
return reinterpret_cast<ConstantInt*>(getOperand(idx*2));
|
return reinterpret_cast<ConstantInt*>(getOperand(idx*2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSuccessorValue - Updates the value associated with the specified
|
||||||
|
// successor.
|
||||||
|
void setSuccessorValue(unsigned idx, ConstantInt* SuccessorValue) {
|
||||||
|
assert(idx < getNumSuccessors() && "Successor # out of range!");
|
||||||
|
setOperand(idx*2, reinterpret_cast<Value*>(SuccessorValue));
|
||||||
|
}
|
||||||
|
|
||||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||||
static inline bool classof(const SwitchInst *) { return true; }
|
static inline bool classof(const SwitchInst *) { return true; }
|
||||||
static inline bool classof(const Instruction *I) {
|
static inline bool classof(const Instruction *I) {
|
||||||
|
@ -2441,7 +2441,7 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
|
|||||||
|
|
||||||
// If there is only the default destination, branch to it if it is not the
|
// If there is only the default destination, branch to it if it is not the
|
||||||
// next basic block. Otherwise, just fall through.
|
// next basic block. Otherwise, just fall through.
|
||||||
if (SI.getNumOperands() == 2) {
|
if (SI.getNumCases() == 1) {
|
||||||
// Update machine-CFG edges.
|
// Update machine-CFG edges.
|
||||||
|
|
||||||
// If this is not a fall-through branch, emit the branch.
|
// If this is not a fall-through branch, emit the branch.
|
||||||
@ -2466,7 +2466,7 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
|
|||||||
// Get the Value to be switched on and default basic blocks, which will be
|
// Get the Value to be switched on and default basic blocks, which will be
|
||||||
// inserted into CaseBlock records, representing basic blocks in the binary
|
// inserted into CaseBlock records, representing basic blocks in the binary
|
||||||
// search tree.
|
// search tree.
|
||||||
const Value *SV = SI.getOperand(0);
|
const Value *SV = SI.getCondition();
|
||||||
|
|
||||||
// Push the initial CaseRec onto the worklist
|
// Push the initial CaseRec onto the worklist
|
||||||
CaseRecVector WorkList;
|
CaseRecVector WorkList;
|
||||||
|
@ -662,18 +662,21 @@ void Interpreter::visitBranchInst(BranchInst &I) {
|
|||||||
|
|
||||||
void Interpreter::visitSwitchInst(SwitchInst &I) {
|
void Interpreter::visitSwitchInst(SwitchInst &I) {
|
||||||
ExecutionContext &SF = ECStack.back();
|
ExecutionContext &SF = ECStack.back();
|
||||||
GenericValue CondVal = getOperandValue(I.getOperand(0), SF);
|
Value* Cond = I.getCondition();
|
||||||
Type *ElTy = I.getOperand(0)->getType();
|
Type *ElTy = Cond->getType();
|
||||||
|
GenericValue CondVal = getOperandValue(Cond, SF);
|
||||||
|
|
||||||
// Check to see if any of the cases match...
|
// Check to see if any of the cases match...
|
||||||
BasicBlock *Dest = 0;
|
BasicBlock *Dest = 0;
|
||||||
for (unsigned i = 2, e = I.getNumOperands(); i != e; i += 2)
|
unsigned NumCases = I.getNumCases();
|
||||||
if (executeICMP_EQ(CondVal, getOperandValue(I.getOperand(i), SF), ElTy)
|
// Skip the first item since that's the default case.
|
||||||
.IntVal != 0) {
|
for (unsigned i = 1; i < NumCases; ++i) {
|
||||||
Dest = cast<BasicBlock>(I.getOperand(i+1));
|
GenericValue CaseVal = getOperandValue(I.getCaseValue(i), SF);
|
||||||
|
if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
|
||||||
|
Dest = cast<BasicBlock>(I.getSuccessor(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
|
if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
|
||||||
SwitchToNewBasicBlock(Dest, SF);
|
SwitchToNewBasicBlock(Dest, SF);
|
||||||
}
|
}
|
||||||
|
@ -2383,22 +2383,29 @@ void CWriter::visitReturnInst(ReturnInst &I) {
|
|||||||
|
|
||||||
void CWriter::visitSwitchInst(SwitchInst &SI) {
|
void CWriter::visitSwitchInst(SwitchInst &SI) {
|
||||||
|
|
||||||
|
Value* Cond = SI.getCondition();
|
||||||
|
|
||||||
Out << " switch (";
|
Out << " switch (";
|
||||||
writeOperand(SI.getOperand(0));
|
writeOperand(Cond);
|
||||||
Out << ") {\n default:\n";
|
Out << ") {\n default:\n";
|
||||||
printPHICopiesForSuccessor (SI.getParent(), SI.getDefaultDest(), 2);
|
printPHICopiesForSuccessor (SI.getParent(), SI.getDefaultDest(), 2);
|
||||||
printBranchToBlock(SI.getParent(), SI.getDefaultDest(), 2);
|
printBranchToBlock(SI.getParent(), SI.getDefaultDest(), 2);
|
||||||
Out << ";\n";
|
Out << ";\n";
|
||||||
for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2) {
|
|
||||||
|
unsigned NumCases = SI.getNumCases();
|
||||||
|
// Skip the first item since that's the default case.
|
||||||
|
for (unsigned i = 1; i < NumCases; ++i) {
|
||||||
|
ConstantInt* CaseVal = SI.getCaseValue(i);
|
||||||
|
BasicBlock* Succ = SI.getSuccessor(i);
|
||||||
Out << " case ";
|
Out << " case ";
|
||||||
writeOperand(SI.getOperand(i));
|
writeOperand(CaseVal);
|
||||||
Out << ":\n";
|
Out << ":\n";
|
||||||
BasicBlock *Succ = cast<BasicBlock>(SI.getOperand(i+1));
|
|
||||||
printPHICopiesForSuccessor (SI.getParent(), Succ, 2);
|
printPHICopiesForSuccessor (SI.getParent(), Succ, 2);
|
||||||
printBranchToBlock(SI.getParent(), Succ, 2);
|
printBranchToBlock(SI.getParent(), Succ, 2);
|
||||||
if (Function::iterator(Succ) == llvm::next(Function::iterator(SI.getParent())))
|
if (Function::iterator(Succ) == llvm::next(Function::iterator(SI.getParent())))
|
||||||
Out << " break;\n";
|
Out << " break;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
Out << " }\n";
|
Out << " }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ namespace {
|
|||||||
void printFunctionHead(const Function *F);
|
void printFunctionHead(const Function *F);
|
||||||
void printFunctionBody(const Function *F);
|
void printFunctionBody(const Function *F);
|
||||||
void printInstruction(const Instruction *I, const std::string& bbname);
|
void printInstruction(const Instruction *I, const std::string& bbname);
|
||||||
std::string getOpName(Value*);
|
std::string getOpName(const Value*);
|
||||||
|
|
||||||
void printModuleBody();
|
void printModuleBody();
|
||||||
};
|
};
|
||||||
@ -979,7 +979,7 @@ void CppWriter::printVariableBody(const GlobalVariable *GV) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CppWriter::getOpName(Value* V) {
|
std::string CppWriter::getOpName(const Value* V) {
|
||||||
if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
|
if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
|
||||||
return getCppName(V);
|
return getCppName(V);
|
||||||
|
|
||||||
@ -1044,14 +1044,17 @@ void CppWriter::printInstruction(const Instruction *I,
|
|||||||
case Instruction::Switch: {
|
case Instruction::Switch: {
|
||||||
const SwitchInst *SI = cast<SwitchInst>(I);
|
const SwitchInst *SI = cast<SwitchInst>(I);
|
||||||
Out << "SwitchInst* " << iName << " = SwitchInst::Create("
|
Out << "SwitchInst* " << iName << " = SwitchInst::Create("
|
||||||
<< opNames[0] << ", "
|
<< getOpName(SI->getCondition()) << ", "
|
||||||
<< opNames[1] << ", "
|
<< getOpName(SI->getDefaultDest()) << ", "
|
||||||
<< SI->getNumCases() << ", " << bbname << ");";
|
<< SI->getNumCases() << ", " << bbname << ");";
|
||||||
nl(Out);
|
nl(Out);
|
||||||
for (unsigned i = 2; i != SI->getNumOperands(); i += 2) {
|
unsigned NumCases = SI->getNumCases();
|
||||||
|
for (unsigned i = 1; i < NumCases; ++i) {
|
||||||
|
const ConstantInt* CaseVal = SI->getCaseValue(i);
|
||||||
|
const BasicBlock* BB = SI->getSuccessor(i);
|
||||||
Out << iName << "->addCase("
|
Out << iName << "->addCase("
|
||||||
<< opNames[i] << ", "
|
<< getOpName(CaseVal) << ", "
|
||||||
<< opNames[i+1] << ");";
|
<< getOpName(BB) << ");";
|
||||||
nl(Out);
|
nl(Out);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1237,11 +1237,17 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) {
|
|||||||
if (I->getOpcode() == Instruction::Add)
|
if (I->getOpcode() == Instruction::Add)
|
||||||
if (ConstantInt *AddRHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
if (ConstantInt *AddRHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
|
||||||
// change 'switch (X+4) case 1:' into 'switch (X) case -3'
|
// change 'switch (X+4) case 1:' into 'switch (X) case -3'
|
||||||
for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2)
|
unsigned NumCases = SI.getNumCases();
|
||||||
SI.setOperand(i,
|
// Skip the first item since that's the default case.
|
||||||
ConstantExpr::getSub(cast<Constant>(SI.getOperand(i)),
|
for (unsigned i = 1; i < NumCases; ++i) {
|
||||||
AddRHS));
|
ConstantInt* CaseVal = SI.getCaseValue(i);
|
||||||
SI.setOperand(0, I->getOperand(0));
|
Constant* NewCaseVal = ConstantExpr::getSub(cast<Constant>(CaseVal),
|
||||||
|
AddRHS);
|
||||||
|
assert(isa<ConstantInt>(NewCaseVal) &&
|
||||||
|
"Result of expression should be constant");
|
||||||
|
SI.setSuccessorValue(i, cast<ConstantInt>(NewCaseVal));
|
||||||
|
}
|
||||||
|
SI.setCondition(I->getOperand(0));
|
||||||
Worklist.Add(I);
|
Worklist.Add(I);
|
||||||
return &SI;
|
return &SI;
|
||||||
}
|
}
|
||||||
|
@ -277,11 +277,11 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI) {
|
|||||||
BasicBlock *CurBlock = SI->getParent();
|
BasicBlock *CurBlock = SI->getParent();
|
||||||
BasicBlock *OrigBlock = CurBlock;
|
BasicBlock *OrigBlock = CurBlock;
|
||||||
Function *F = CurBlock->getParent();
|
Function *F = CurBlock->getParent();
|
||||||
Value *Val = SI->getOperand(0); // The value we are switching on...
|
Value *Val = SI->getCondition(); // The value we are switching on...
|
||||||
BasicBlock* Default = SI->getDefaultDest();
|
BasicBlock* Default = SI->getDefaultDest();
|
||||||
|
|
||||||
// If there is only the default destination, don't bother with the code below.
|
// If there is only the default destination, don't bother with the code below.
|
||||||
if (SI->getNumOperands() == 2) {
|
if (SI->getNumCases() == 1) {
|
||||||
BranchInst::Create(SI->getDefaultDest(), CurBlock);
|
BranchInst::Create(SI->getDefaultDest(), CurBlock);
|
||||||
CurBlock->getInstList().erase(SI);
|
CurBlock->getInstList().erase(SI);
|
||||||
return;
|
return;
|
||||||
|
@ -1702,18 +1702,20 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
|
|||||||
writeOperand(BI.getSuccessor(1), true);
|
writeOperand(BI.getSuccessor(1), true);
|
||||||
|
|
||||||
} else if (isa<SwitchInst>(I)) {
|
} else if (isa<SwitchInst>(I)) {
|
||||||
|
SwitchInst& SI(cast<SwitchInst>(I));
|
||||||
// Special case switch instruction to get formatting nice and correct.
|
// Special case switch instruction to get formatting nice and correct.
|
||||||
Out << ' ';
|
Out << ' ';
|
||||||
writeOperand(Operand , true);
|
writeOperand(SI.getCondition(), true);
|
||||||
Out << ", ";
|
Out << ", ";
|
||||||
writeOperand(I.getOperand(1), true);
|
writeOperand(SI.getDefaultDest(), true);
|
||||||
Out << " [";
|
Out << " [";
|
||||||
|
// Skip the first item since that's the default case.
|
||||||
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
|
unsigned NumCases = SI.getNumCases();
|
||||||
|
for (unsigned i = 1; i < NumCases; ++i) {
|
||||||
Out << "\n ";
|
Out << "\n ";
|
||||||
writeOperand(I.getOperand(op ), true);
|
writeOperand(SI.getCaseValue(i), true);
|
||||||
Out << ", ";
|
Out << ", ";
|
||||||
writeOperand(I.getOperand(op+1), true);
|
writeOperand(SI.getSuccessor(i), true);
|
||||||
}
|
}
|
||||||
Out << "\n ]";
|
Out << "\n ]";
|
||||||
} else if (isa<IndirectBrInst>(I)) {
|
} else if (isa<IndirectBrInst>(I)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user