56#include "llvm/IR/IntrinsicsS390.h"
70 SystemZTDCLegacy() : FunctionPass(ID) {}
74 void getAnalysisUsage(AnalysisUsage &AU)
const override {
83 MapVector<Instruction *, std::tuple<Value *, int, bool>> ConvertedInsts;
85 std::vector<BinaryOperator *> LogicOpsWorklist;
87 std::set<Instruction *> PossibleJunk;
90 void convertFCmp(CmpInst &
I);
93 void convertICmp(CmpInst &
I);
97 void convertLogicOp(BinaryOperator &
I);
101 void converted(Instruction *
I,
Value *
V,
int Mask,
bool Worthy) {
102 ConvertedInsts[
I] = std::make_tuple(
V, Mask, Worthy);
103 auto &
M = *
I->getFunction()->getParent();
104 auto &Ctx =
M.getContext();
105 for (
auto *U :
I->users()) {
107 if (LI && LI->getType() == Type::getInt1Ty(Ctx) &&
108 (LI->getOpcode() == Instruction::And ||
109 LI->getOpcode() == Instruction::Or ||
110 LI->getOpcode() == Instruction::Xor)) {
111 LogicOpsWorklist.push_back(LI);
122char SystemZTDCLegacy::ID = 0;
124 "SystemZ Test Data Class optimization",
false,
false)
127 return new SystemZTDCLegacy();
130void SystemZTDCImpl::convertFCmp(
CmpInst &
I) {
131 Value *Op0 =
I.getOperand(0);
133 auto Pred =
I.getPredicate();
135 if (!Const || !
Const->getType()->isFloatingPointTy())
140 APFloat NegSmallest = Smallest;
144 if (
Const->isZero()) {
147 }
else if (
Const->isInfinity()) {
149 WhichConst =
Const->isNegative() ? 2 : 1;
150 }
else if (
Const->isExactlyValue(Smallest)) {
156 }
else if (
Const->isExactlyValue(NegSmallest)) {
167 static const int Masks[][4] = {
214 Mask |= Masks[WhichConst][0];
216 Mask |= Masks[WhichConst][1];
218 Mask |= Masks[WhichConst][2];
220 Mask |= Masks[WhichConst][3];
226 if (
F &&
F->getIntrinsicID() == Intrinsic::fabs) {
230 Op0 = CI->getArgOperand(0);
233 Worthy = WhichConst != 0;
234 PossibleJunk.insert(CI);
237 converted(&
I, Op0, Mask, Worthy);
240void SystemZTDCImpl::convertICmp(CmpInst &
I) {
241 Value *Op0 =
I.getOperand(0);
243 auto Pred =
I.getPredicate();
249 if (!Cast->getSrcTy()->isFloatTy() &&
250 !Cast->getSrcTy()->isDoubleTy() &&
251 !Cast->getSrcTy()->isFP128Ty())
253 Value *
V = Cast->getOperand(0);
265 PossibleJunk.insert(Cast);
266 converted(&
I,
V, Mask,
true);
270 if (!
F ||
F->getIntrinsicID() != Intrinsic::s390_tdc)
272 if (!
Const->isZero())
274 Value *
V = CI->getArgOperand(0);
279 int Mask = MaskC->getZExtValue();
290 PossibleJunk.insert(CI);
291 converted(&
I,
V, Mask,
false);
295void SystemZTDCImpl::convertLogicOp(BinaryOperator &
I) {
298 bool Worthy0, Worthy1;
304 switch (
I.getOpcode()) {
305 case Instruction::And:
306 Mask = Mask0 & Mask1;
308 case Instruction::Or:
309 Mask = Mask0 | Mask1;
311 case Instruction::Xor:
312 Mask = Mask0 ^ Mask1;
317 converted(&
I, Op0, Mask,
true);
320bool SystemZTDCImpl::runOnFunction(
Function &
F, SystemZTargetMachine &TM) {
324 ConvertedInsts.
clear();
325 LogicOpsWorklist.clear();
326 PossibleJunk.clear();
330 if (
I.getOpcode() == Instruction::FCmp)
332 else if (
I.getOpcode() == Instruction::ICmp)
337 if (ConvertedInsts.
empty())
341 while (!LogicOpsWorklist.empty()) {
342 BinaryOperator *
Op = LogicOpsWorklist.back();
343 LogicOpsWorklist.pop_back();
356 auto &Ctx =
M.getContext();
357 Value *Zero32 = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
358 bool MadeChange =
false;
359 for (
auto &It :
reverse(ConvertedInsts)) {
364 std::tie(
V, Mask, Worthy) = It.second;
365 if (!
I->user_empty()) {
371 Value *MaskVal = ConstantInt::get(Type::getInt64Ty(Ctx), Mask);
373 IRB.CreateIntrinsic(Intrinsic::s390_tdc,
V->getType(), {V, MaskVal});
375 I->replaceAllUsesWith(ICmp);
378 I->eraseFromParent();
387 for (
auto *
I : PossibleJunk)
389 I->eraseFromParent();
394bool SystemZTDCLegacy::runOnFunction(
Function &
F) {
395 auto &TPC = getAnalysis<TargetPassConfig>();
397 return Impl.runOnFunction(
F, TPC.getTM<SystemZTargetMachine>());
403 bool Changed = Impl.runOnFunction(
F, TM);
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
FunctionAnalysisManager FAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Target-Independent Code Generator Pass Configuration Options pass.
static APFloat getSmallestNormalized(const fltSemantics &Sem, bool Negative=false)
Returns the smallest (by magnitude) normalized finite number in the given semantics.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
This class is the base class for the comparison instructions.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_SGT
signed greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
FunctionPass class - This class is used to implement most global optimizations.
size_type count(const KeyT &Key) const
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
LLVM_ABI const fltSemantics & getFltSemantics() const
Type * getType() const
All values are typed, get the type of this value.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
const unsigned TDCMASK_NEGATIVE
const unsigned TDCMASK_NORMAL_MINUS
const unsigned TDCMASK_MINUS
const unsigned TDCMASK_SUBNORMAL_MINUS
const unsigned TDCMASK_ZERO
const unsigned TDCMASK_NORMAL_PLUS
const unsigned TDCMASK_ALL
const unsigned TDCMASK_SUBNORMAL_PLUS
const unsigned TDCMASK_INFINITY_PLUS
const unsigned TDCMASK_POSITIVE
const unsigned TDCMASK_INFINITY_MINUS
const unsigned TDCMASK_NAN
const unsigned TDCMASK_PLUS
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
FunctionPass * createSystemZTDCLegacyPass()
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.