mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Teach SimplifyCFG about magic pointer constants.
Weird code sometimes uses pointer constants other than null. This patch teaches SimplifyCFG to build switch instructions in those cases. Code like this: void f(const char *x) { if (!x) puts("null"); else if ((uintptr_t)x == 1) puts("one"); else if (x == (char*)2 || x == (char*)3) puts("two"); else if ((intptr_t)x == 4) puts("four"); else puts(x); } Now becomes a switch: define void @f(i8* %x) nounwind ssp { entry: %magicptr23 = ptrtoint i8* %x to i64 ; <i64> [#uses=1] switch i64 %magicptr23, label %if.else16 [ i64 0, label %if.then i64 1, label %if.then2 i64 2, label %if.then9 i64 3, label %if.then9 i64 4, label %if.then14 ] Note that LLVM's own DenseMap uses magic pointers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
@@ -261,7 +262,7 @@ static bool MergeEmptyReturnBlocks(Function &F) {
|
||||
|
||||
/// IterativeSimplifyCFG - Call SimplifyCFG on all the blocks in the function,
|
||||
/// iterating until no more changes are made.
|
||||
static bool IterativeSimplifyCFG(Function &F) {
|
||||
static bool IterativeSimplifyCFG(Function &F, const TargetData *TD) {
|
||||
bool Changed = false;
|
||||
bool LocalChange = true;
|
||||
while (LocalChange) {
|
||||
@@ -271,7 +272,7 @@ static bool IterativeSimplifyCFG(Function &F) {
|
||||
// if they are unneeded...
|
||||
//
|
||||
for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
|
||||
if (SimplifyCFG(BBIt++)) {
|
||||
if (SimplifyCFG(BBIt++, TD)) {
|
||||
LocalChange = true;
|
||||
++NumSimpl;
|
||||
}
|
||||
@@ -285,10 +286,11 @@ static bool IterativeSimplifyCFG(Function &F) {
|
||||
// simplify the CFG.
|
||||
//
|
||||
bool CFGSimplifyPass::runOnFunction(Function &F) {
|
||||
const TargetData *TD = getAnalysisIfAvailable<TargetData>();
|
||||
bool EverChanged = RemoveUnreachableBlocksFromFn(F);
|
||||
EverChanged |= MergeEmptyReturnBlocks(F);
|
||||
EverChanged |= IterativeSimplifyCFG(F);
|
||||
|
||||
EverChanged |= IterativeSimplifyCFG(F, TD);
|
||||
|
||||
// If neither pass changed anything, we're done.
|
||||
if (!EverChanged) return false;
|
||||
|
||||
@@ -299,11 +301,11 @@ bool CFGSimplifyPass::runOnFunction(Function &F) {
|
||||
// RemoveUnreachableBlocksFromFn doesn't do anything.
|
||||
if (!RemoveUnreachableBlocksFromFn(F))
|
||||
return true;
|
||||
|
||||
|
||||
do {
|
||||
EverChanged = IterativeSimplifyCFG(F);
|
||||
EverChanged = IterativeSimplifyCFG(F, TD);
|
||||
EverChanged |= RemoveUnreachableBlocksFromFn(F);
|
||||
} while (EverChanged);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user