#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
namespace {
-class RISCVCodeGenPrepare : public FunctionPass {
+class RISCVCodeGenPrepare : public FunctionPass,
+ public InstVisitor<RISCVCodeGenPrepare, bool> {
const DataLayout *DL;
const RISCVSubtarget *ST;
AU.addRequired<TargetPassConfig>();
}
-private:
- bool optimizeZExt(ZExtInst *I);
- bool optimizeAndExt(BinaryOperator *BO);
+ bool visitInstruction(Instruction &I) { return false; }
+ bool visitZExtInst(ZExtInst &I);
+ bool visitAnd(BinaryOperator &BO);
};
} // end anonymous namespace
-bool RISCVCodeGenPrepare::optimizeZExt(ZExtInst *ZExt) {
+bool RISCVCodeGenPrepare::visitZExtInst(ZExtInst &ZExt) {
if (!ST->is64Bit())
return false;
- Value *Src = ZExt->getOperand(0);
+ Value *Src = ZExt.getOperand(0);
// We only care about ZExt from i32 to i64.
- if (!ZExt->getType()->isIntegerTy(64) || !Src->getType()->isIntegerTy(32))
+ if (!ZExt.getType()->isIntegerTy(64) || !Src->getType()->isIntegerTy(32))
return false;
// Look for an opportunity to replace (i64 (zext (i32 X))) with a sext if we
// can determine that the sign bit of X is zero via a dominating condition.
// This often occurs with widened induction variables.
if (isImpliedByDomCondition(ICmpInst::ICMP_SGE, Src,
- Constant::getNullValue(Src->getType()), ZExt,
+ Constant::getNullValue(Src->getType()), &ZExt,
*DL)) {
- auto *SExt = new SExtInst(Src, ZExt->getType(), "", ZExt);
- SExt->takeName(ZExt);
- SExt->setDebugLoc(ZExt->getDebugLoc());
+ auto *SExt = new SExtInst(Src, ZExt.getType(), "", &ZExt);
+ SExt->takeName(&ZExt);
+ SExt->setDebugLoc(ZExt.getDebugLoc());
- ZExt->replaceAllUsesWith(SExt);
- ZExt->eraseFromParent();
+ ZExt.replaceAllUsesWith(SExt);
+ ZExt.eraseFromParent();
++NumZExtToSExt;
return true;
}
// INT_MIN is poison, the sign bit is zero.
using namespace PatternMatch;
if (match(Src, m_Intrinsic<Intrinsic::abs>(m_Value(), m_One()))) {
- auto *SExt = new SExtInst(Src, ZExt->getType(), "", ZExt);
- SExt->takeName(ZExt);
- SExt->setDebugLoc(ZExt->getDebugLoc());
+ auto *SExt = new SExtInst(Src, ZExt.getType(), "", &ZExt);
+ SExt->takeName(&ZExt);
+ SExt->setDebugLoc(ZExt.getDebugLoc());
- ZExt->replaceAllUsesWith(SExt);
- ZExt->eraseFromParent();
+ ZExt.replaceAllUsesWith(SExt);
+ ZExt.eraseFromParent();
++NumZExtToSExt;
return true;
}
// but bits 63:32 are zero. If we can prove that bit 31 of X is 0, we can fill
// the upper 32 bits with ones. A separate transform will turn (zext X) into
// (sext X) for the same condition.
-bool RISCVCodeGenPrepare::optimizeAndExt(BinaryOperator *BO) {
+bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) {
if (!ST->is64Bit())
return false;
- if (BO->getOpcode() != Instruction::And)
- return false;
-
- if (!BO->getType()->isIntegerTy(64))
+ if (!BO.getType()->isIntegerTy(64))
return false;
// Left hand side should be sext or zext.
- Instruction *LHS = dyn_cast<Instruction>(BO->getOperand(0));
+ Instruction *LHS = dyn_cast<Instruction>(BO.getOperand(0));
if (!LHS || (!isa<SExtInst>(LHS) && !isa<ZExtInst>(LHS)))
return false;
return false;
// Right hand side should be a constant.
- Value *RHS = BO->getOperand(1);
+ Value *RHS = BO.getOperand(1);
auto *CI = dyn_cast<ConstantInt>(RHS);
if (!CI)
// Sign extend the constant and replace the And operand.
C = SignExtend64<32>(C);
- BO->setOperand(1, ConstantInt::get(LHS->getType(), C));
+ BO.setOperand(1, ConstantInt::get(LHS->getType(), C));
return true;
}
DL = &F.getParent()->getDataLayout();
bool MadeChange = false;
- for (auto &BB : F) {
- for (Instruction &I : llvm::make_early_inc_range(BB)) {
- if (auto *ZExt = dyn_cast<ZExtInst>(&I))
- MadeChange |= optimizeZExt(ZExt);
- else if (I.getOpcode() == Instruction::And)
- MadeChange |= optimizeAndExt(cast<BinaryOperator>(&I));
- }
- }
+ for (auto &BB : F)
+ for (Instruction &I : llvm::make_early_inc_range(BB))
+ MadeChange |= visit(I);
return MadeChange;
}