mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Optimized usage of new SwitchInst case values (IntegersSubset type) in Local.cpp, Execution.cpp and BitcodeWriter.cpp.
I got about 1% of compile-time improvement on my machines (Ubuntu 11.10 i386 and Ubuntu 12.04 x64). llvm-svn: 159076
This commit is contained in:
parent
7067c92fbb
commit
bc2affc34a
@ -2705,8 +2705,7 @@ public:
|
||||
}
|
||||
|
||||
/// Resolves case value for current case.
|
||||
// IntegersSubsetRef getCaseValueEx() {
|
||||
IntegersSubset getCaseValueEx() {
|
||||
IntegersSubsetRef getCaseValueEx() {
|
||||
assert(Index < SI->getNumCases() && "Index out the number of cases.");
|
||||
return *SubsetIt;
|
||||
}
|
||||
|
@ -1157,19 +1157,38 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||
Vals64.push_back(SI.getNumCases());
|
||||
for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
|
||||
i != e; ++i) {
|
||||
IntegersSubset CaseRanges = i.getCaseValueEx();
|
||||
Vals64.push_back(CaseRanges.getNumItems());
|
||||
for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
|
||||
IntegersSubset::Range r = CaseRanges.getItem(ri);
|
||||
bool IsSingleNumber = r.isSingleNumber();
|
||||
|
||||
Vals64.push_back(IsSingleNumber);
|
||||
|
||||
unsigned Code, Abbrev; // will unused.
|
||||
IntegersSubset& CaseRanges = i.getCaseValueEx();
|
||||
unsigned Code, Abbrev; // will unused.
|
||||
|
||||
if (CaseRanges.isSingleNumber()) {
|
||||
Vals64.push_back(1/*NumItems = 1*/);
|
||||
Vals64.push_back(true/*IsSingleNumber = true*/);
|
||||
EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
|
||||
} else {
|
||||
|
||||
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
|
||||
if (!IsSingleNumber)
|
||||
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
|
||||
Vals64.push_back(CaseRanges.getNumItems());
|
||||
|
||||
if (CaseRanges.isSingleNumbersOnly()) {
|
||||
for (unsigned ri = 0, rn = CaseRanges.getNumItems();
|
||||
ri != rn; ++ri) {
|
||||
|
||||
Vals64.push_back(true/*IsSingleNumber = true*/);
|
||||
|
||||
EmitAPInt(Vals64, Code, Abbrev,
|
||||
CaseRanges.getSingleNumber(ri), true);
|
||||
}
|
||||
} else
|
||||
for (unsigned ri = 0, rn = CaseRanges.getNumItems();
|
||||
ri != rn; ++ri) {
|
||||
IntegersSubset::Range r = CaseRanges.getItem(ri);
|
||||
bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
|
||||
|
||||
Vals64.push_back(IsSingleNumber);
|
||||
|
||||
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
|
||||
if (!IsSingleNumber)
|
||||
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
|
||||
}
|
||||
}
|
||||
Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
|
||||
}
|
||||
|
@ -651,20 +651,40 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
|
||||
// Check to see if any of the cases match...
|
||||
BasicBlock *Dest = 0;
|
||||
for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
|
||||
IntegersSubset Case = i.getCaseValueEx();
|
||||
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
|
||||
IntegersSubset::Range r = Case.getItem(n);
|
||||
IntegersSubset& Case = i.getCaseValueEx();
|
||||
if (Case.isSingleNumber()) {
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
const ConstantInt *LowCI = r.getLow().toConstantInt();
|
||||
const ConstantInt *HighCI = r.getHigh().toConstantInt();
|
||||
GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
|
||||
GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
|
||||
if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
|
||||
executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
|
||||
const ConstantInt *CI = Case.getSingleNumber(0).toConstantInt();
|
||||
GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
|
||||
if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
|
||||
Dest = cast<BasicBlock>(i.getCaseSuccessor());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Case.isSingleNumbersOnly()) {
|
||||
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
const ConstantInt *CI = Case.getSingleNumber(n).toConstantInt();
|
||||
GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
|
||||
if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
|
||||
Dest = cast<BasicBlock>(i.getCaseSuccessor());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
|
||||
IntegersSubset::Range r = Case.getItem(n);
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
const ConstantInt *LowCI = r.getLow().toConstantInt();
|
||||
const ConstantInt *HighCI = r.getHigh().toConstantInt();
|
||||
GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
|
||||
GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
|
||||
if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
|
||||
executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
|
||||
Dest = cast<BasicBlock>(i.getCaseSuccessor());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
|
||||
SwitchToNewBasicBlock(Dest, SF);
|
||||
|
@ -169,11 +169,11 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
|
||||
// Otherwise, we can fold this switch into a conditional branch
|
||||
// instruction if it has only one non-default destination.
|
||||
SwitchInst::CaseIt FirstCase = SI->case_begin();
|
||||
IntegersSubset CaseRanges = FirstCase.getCaseValueEx();
|
||||
if (CaseRanges.getNumItems() == 1 && CaseRanges.isSingleNumber(0)) {
|
||||
IntegersSubset& Case = FirstCase.getCaseValueEx();
|
||||
if (Case.isSingleNumber()) {
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
|
||||
CaseRanges.getItem(0).getLow().toConstantInt(),
|
||||
Case.getSingleNumber(0).toConstantInt(),
|
||||
"cond");
|
||||
|
||||
// Insert the new branch.
|
||||
@ -183,7 +183,6 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
|
||||
// Delete the old switch.
|
||||
SI->eraseFromParent();
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user