mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-02 07:41:38 +00:00
add DEBUG and -stats output to earlycse.
Teach it to CSE the rest of the non-side-effecting instructions. llvm-svn: 122716
This commit is contained in:
parent
dbad0b5e40
commit
39d1fb3320
@ -14,15 +14,21 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "early-cse"
|
#define DEBUG_TYPE "early-cse"
|
||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm/Analysis/InstructionSimplify.h"
|
#include "llvm/Analysis/InstructionSimplify.h"
|
||||||
#include "llvm/Analysis/InstructionSimplify.h"
|
#include "llvm/Analysis/InstructionSimplify.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/ADT/ScopedHashTable.h"
|
#include "llvm/ADT/ScopedHashTable.h"
|
||||||
|
#include "llvm/ADT/Statistic.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
STATISTIC(NumSimplify, "Number of insts simplified or DCE'd");
|
||||||
|
STATISTIC(NumCSE, "Number of insts CSE'd");
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/// InstValue - Instances of this struct represent available values in the
|
/// InstValue - Instances of this struct represent available values in the
|
||||||
/// scoped hash table.
|
/// scoped hash table.
|
||||||
@ -35,7 +41,11 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool canHandle(Instruction *Inst) {
|
static bool canHandle(Instruction *Inst) {
|
||||||
return isa<CastInst>(Inst);
|
return isa<CastInst>(Inst) || isa<BinaryOperator>(Inst) ||
|
||||||
|
isa<GetElementPtrInst>(Inst) || isa<CmpInst>(Inst) ||
|
||||||
|
isa<SelectInst>(Inst) || isa<ExtractElementInst>(Inst) ||
|
||||||
|
isa<InsertElementInst>(Inst) || isa<ShuffleVectorInst>(Inst) ||
|
||||||
|
isa<ExtractValueInst>(Inst) || isa<InsertValueInst>(Inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static InstValue get(Instruction *I) {
|
static InstValue get(Instruction *I) {
|
||||||
@ -73,8 +83,24 @@ unsigned DenseMapInfo<InstValue>::getHashValue(InstValue Val) {
|
|||||||
unsigned Res = 0;
|
unsigned Res = 0;
|
||||||
if (CastInst *CI = dyn_cast<CastInst>(Inst))
|
if (CastInst *CI = dyn_cast<CastInst>(Inst))
|
||||||
Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType());
|
Res = getHash(CI->getOperand(0)) ^ getHash(CI->getType());
|
||||||
else
|
else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Inst))
|
||||||
assert(0 && "Unhandled instruction kind");
|
Res = getHash(BO->getOperand(0)) ^ (getHash(BO->getOperand(1)) << 1);
|
||||||
|
else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) {
|
||||||
|
Res = getHash(CI->getOperand(0));
|
||||||
|
for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
|
||||||
|
Res ^= getHash(CI->getOperand(i)) << i;
|
||||||
|
} else if (CmpInst *CI = dyn_cast<CmpInst>(Inst)) {
|
||||||
|
Res = getHash(CI->getOperand(0)) ^ (getHash(CI->getOperand(1)) << 1) ^
|
||||||
|
CI->getPredicate();
|
||||||
|
} else {
|
||||||
|
assert((isa<SelectInst>(Inst) || isa<ExtractElementInst>(Inst) ||
|
||||||
|
isa<InsertElementInst>(Inst) || isa<ShuffleVectorInst>(Inst) ||
|
||||||
|
isa<ExtractValueInst>(Inst) || isa<InsertValueInst>(Inst)) &&
|
||||||
|
"Unhandled instruction kind");
|
||||||
|
Res = getHash(CI->getType()) << 4;
|
||||||
|
for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
|
||||||
|
Res ^= getHash(CI->getOperand(i)) << i;
|
||||||
|
}
|
||||||
|
|
||||||
return (Res << 1) ^ Inst->getOpcode();
|
return (Res << 1) ^ Inst->getOpcode();
|
||||||
}
|
}
|
||||||
@ -152,17 +178,21 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
|
|||||||
|
|
||||||
// Dead instructions should just be removed.
|
// Dead instructions should just be removed.
|
||||||
if (isInstructionTriviallyDead(Inst)) {
|
if (isInstructionTriviallyDead(Inst)) {
|
||||||
|
DEBUG(dbgs() << "EarlyCSE DCE: " << *Inst << '\n');
|
||||||
Inst->eraseFromParent();
|
Inst->eraseFromParent();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
++NumSimplify;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the instruction can be simplified (e.g. X+0 = X) then replace it with
|
// If the instruction can be simplified (e.g. X+0 = X) then replace it with
|
||||||
// its simpler value.
|
// its simpler value.
|
||||||
if (Value *V = SimplifyInstruction(Inst, TD, DT)) {
|
if (Value *V = SimplifyInstruction(Inst, TD, DT)) {
|
||||||
|
DEBUG(dbgs() << "EarlyCSE Simplify: " << *Inst << " to: " << *V << '\n');
|
||||||
Inst->replaceAllUsesWith(V);
|
Inst->replaceAllUsesWith(V);
|
||||||
Inst->eraseFromParent();
|
Inst->eraseFromParent();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
++NumSimplify;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +202,11 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
|
|||||||
|
|
||||||
// See if the instruction has an available value. If so, use it.
|
// See if the instruction has an available value. If so, use it.
|
||||||
if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) {
|
if (Instruction *V = AvailableValues->lookup(InstValue::get(Inst))) {
|
||||||
|
DEBUG(dbgs() << "EarlyCSE CSE: " << *Inst << " to: " << *V << '\n');
|
||||||
Inst->replaceAllUsesWith(V);
|
Inst->replaceAllUsesWith(V);
|
||||||
Inst->eraseFromParent();
|
Inst->eraseFromParent();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
++NumCSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,10 @@
|
|||||||
// void foo(_Complex float *P)
|
// void foo(_Complex float *P)
|
||||||
// for (i) { __real__(*P) = 0; __imag__(*P) = 0; }
|
// for (i) { __real__(*P) = 0; __imag__(*P) = 0; }
|
||||||
// this is also "Example 2" from http://blog.regehr.org/archives/320
|
// this is also "Example 2" from http://blog.regehr.org/archives/320
|
||||||
//
|
//
|
||||||
|
// This could regognize common matrix multiplies and dot product idioms and
|
||||||
|
// replace them with calls to BLAS (if linked in??).
|
||||||
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#define DEBUG_TYPE "loop-idiom"
|
#define DEBUG_TYPE "loop-idiom"
|
||||||
@ -49,8 +52,6 @@
|
|||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// TODO: Recognize "N" size array multiplies: replace with call to blas or
|
|
||||||
// something.
|
|
||||||
STATISTIC(NumMemSet, "Number of memset's formed from loop stores");
|
STATISTIC(NumMemSet, "Number of memset's formed from loop stores");
|
||||||
STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores");
|
STATISTIC(NumMemCpy, "Number of memcpy's formed from loop load+stores");
|
||||||
|
|
||||||
|
@ -6,16 +6,27 @@ define void @test1(i8 %V, i32 *%P) {
|
|||||||
%A = bitcast i64 42 to double ;; dead
|
%A = bitcast i64 42 to double ;; dead
|
||||||
%B = add i32 4, 19 ;; constant folds
|
%B = add i32 4, 19 ;; constant folds
|
||||||
store i32 %B, i32* %P
|
store i32 %B, i32* %P
|
||||||
|
|
||||||
; CHECK-NEXT: store i32 23, i32* %P
|
; CHECK-NEXT: store i32 23, i32* %P
|
||||||
|
|
||||||
%C = zext i8 %V to i32
|
%C = zext i8 %V to i32
|
||||||
%D = zext i8 %V to i32 ;; CSE
|
%D = zext i8 %V to i32 ;; CSE
|
||||||
volatile store i32 %C, i32* %P
|
volatile store i32 %C, i32* %P
|
||||||
volatile store i32 %D, i32* %P
|
volatile store i32 %D, i32* %P
|
||||||
|
|
||||||
; CHECK-NEXT: %C = zext i8 %V to i32
|
; CHECK-NEXT: %C = zext i8 %V to i32
|
||||||
; CHECK-NEXT: volatile store i32 %C
|
; CHECK-NEXT: volatile store i32 %C
|
||||||
; CHECK-NEXT: volatile store i32 %C
|
; CHECK-NEXT: volatile store i32 %C
|
||||||
|
|
||||||
|
%E = add i32 %C, %C
|
||||||
|
%F = add i32 %C, %C
|
||||||
|
volatile store i32 %E, i32* %P
|
||||||
|
volatile store i32 %F, i32* %P
|
||||||
|
; CHECK-NEXT: %E = add i32 %C, %C
|
||||||
|
; CHECK-NEXT: volatile store i32 %E
|
||||||
|
; CHECK-NEXT: volatile store i32 %E
|
||||||
|
|
||||||
|
%G = add nuw i32 %C, %C ;; not a CSE with E
|
||||||
|
volatile store i32 %G, i32* %P
|
||||||
|
; CHECK-NEXT: %G = add nuw i32 %C, %C
|
||||||
|
; CHECK-NEXT: volatile store i32 %G
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user