54#include "llvm/IR/IntrinsicsS390.h"
67 SystemZTDCPass() : FunctionPass(ID) {}
71 void getAnalysisUsage(AnalysisUsage &AU)
const override {
78 MapVector<Instruction *, std::tuple<Value *, int, bool>> ConvertedInsts;
80 std::vector<BinaryOperator *> LogicOpsWorklist;
82 std::set<Instruction *> PossibleJunk;
85 void convertFCmp(CmpInst &
I);
88 void convertICmp(CmpInst &
I);
92 void convertLogicOp(BinaryOperator &
I);
96 void converted(Instruction *
I,
Value *V,
int Mask,
bool Worthy) {
97 ConvertedInsts[
I] = std::make_tuple(V, Mask, Worthy);
98 auto &
M = *
I->getFunction()->getParent();
99 auto &Ctx =
M.getContext();
100 for (
auto *U :
I->users()) {
102 if (LI && LI->getType() == Type::getInt1Ty(Ctx) &&
103 (LI->getOpcode() == Instruction::And ||
104 LI->getOpcode() == Instruction::Or ||
105 LI->getOpcode() == Instruction::Xor)) {
106 LogicOpsWorklist.push_back(LI);
114char SystemZTDCPass::ID = 0;
116 "SystemZ Test Data Class optimization",
false,
false)
119 return new SystemZTDCPass();
122void SystemZTDCPass::convertFCmp(
CmpInst &
I) {
123 Value *Op0 =
I.getOperand(0);
125 auto Pred =
I.getPredicate();
132 APFloat NegSmallest = Smallest;
136 if (
Const->isZero()) {
139 }
else if (
Const->isInfinity()) {
141 WhichConst =
Const->isNegative() ? 2 : 1;
142 }
else if (
Const->isExactlyValue(Smallest)) {
148 }
else if (
Const->isExactlyValue(NegSmallest)) {
159 static const int Masks[][4] = {
206 Mask |= Masks[WhichConst][0];
208 Mask |= Masks[WhichConst][1];
210 Mask |= Masks[WhichConst][2];
212 Mask |= Masks[WhichConst][3];
218 if (
F &&
F->getIntrinsicID() == Intrinsic::fabs) {
222 Op0 = CI->getArgOperand(0);
225 Worthy = WhichConst != 0;
226 PossibleJunk.insert(CI);
229 converted(&
I, Op0, Mask, Worthy);
232void SystemZTDCPass::convertICmp(CmpInst &
I) {
233 Value *Op0 =
I.getOperand(0);
235 auto Pred =
I.getPredicate();
241 if (!Cast->getSrcTy()->isFloatTy() &&
242 !Cast->getSrcTy()->isDoubleTy() &&
243 !Cast->getSrcTy()->isFP128Ty())
245 Value *
V = Cast->getOperand(0);
257 PossibleJunk.insert(Cast);
258 converted(&
I, V, Mask,
true);
262 if (!
F ||
F->getIntrinsicID() != Intrinsic::s390_tdc)
264 if (!
Const->isZero())
266 Value *
V = CI->getArgOperand(0);
271 int Mask = MaskC->getZExtValue();
282 PossibleJunk.insert(CI);
283 converted(&
I, V, Mask,
false);
287void SystemZTDCPass::convertLogicOp(BinaryOperator &
I) {
290 bool Worthy0, Worthy1;
296 switch (
I.getOpcode()) {
297 case Instruction::And:
298 Mask = Mask0 & Mask1;
300 case Instruction::Or:
301 Mask = Mask0 | Mask1;
303 case Instruction::Xor:
304 Mask = Mask0 ^ Mask1;
309 converted(&
I, Op0, Mask,
true);
312bool SystemZTDCPass::runOnFunction(Function &
F) {
313 auto &TPC = getAnalysis<TargetPassConfig>();
314 if (TPC.getTM<TargetMachine>()
315 .getSubtarget<SystemZSubtarget>(
F)
319 ConvertedInsts.
clear();
320 LogicOpsWorklist.clear();
321 PossibleJunk.clear();
325 if (
I.getOpcode() == Instruction::FCmp)
327 else if (
I.getOpcode() == Instruction::ICmp)
332 if (ConvertedInsts.
empty())
336 while (!LogicOpsWorklist.empty()) {
337 BinaryOperator *
Op = LogicOpsWorklist.back();
338 LogicOpsWorklist.pop_back();
351 auto &Ctx =
M.getContext();
352 Value *Zero32 = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
353 bool MadeChange =
false;
354 for (
auto &It :
reverse(ConvertedInsts)) {
359 std::tie(V, Mask, Worthy) = It.second;
360 if (!
I->user_empty()) {
366 Value *MaskVal = ConstantInt::get(Type::getInt64Ty(Ctx), Mask);
368 IRB.CreateIntrinsic(Intrinsic::s390_tdc,
V->getType(), {V, MaskVal});
370 I->replaceAllUsesWith(ICmp);
373 I->eraseFromParent();
382 for (
auto *
I : PossibleJunk)
384 I->eraseFromParent();
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.
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#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()
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
LLVM_ABI const fltSemantics & getFltSemantics() const
Type * getType() const
All values are typed, get the type of this value.
#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.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto reverse(ContainerTy &&C)
FunctionPass * createSystemZTDCPass()
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.