55#include "llvm/IR/IntrinsicsS390.h"
84 std::vector<BinaryOperator *> LogicOpsWorklist;
86 std::set<Instruction *> PossibleJunk;
101 ConvertedInsts[
I] = std::make_tuple(V, Mask, Worthy);
102 auto &
M = *
I->getFunction()->getParent();
103 auto &Ctx =
M.getContext();
104 for (
auto *U :
I->users()) {
105 auto *LI = dyn_cast<BinaryOperator>(U);
107 (LI->getOpcode() == Instruction::And ||
108 LI->getOpcode() == Instruction::Or ||
109 LI->getOpcode() == Instruction::Xor)) {
110 LogicOpsWorklist.push_back(LI);
118char SystemZTDCPass::ID = 0;
120 "SystemZ Test Data Class optimization",
false,
false)
123 return new SystemZTDCPass();
126void SystemZTDCPass::convertFCmp(
CmpInst &
I) {
127 Value *Op0 =
I.getOperand(0);
128 auto *
Const = dyn_cast<ConstantFP>(
I.getOperand(1));
129 auto Pred =
I.getPredicate();
136 APFloat NegSmallest = Smallest;
140 if (
Const->isZero()) {
143 }
else if (
Const->isInfinity()) {
145 WhichConst =
Const->isNegative() ? 2 : 1;
146 }
else if (
Const->isExactlyValue(Smallest)) {
152 }
else if (
Const->isExactlyValue(NegSmallest)) {
163 static const int Masks[][4] = {
210 Mask |= Masks[WhichConst][0];
212 Mask |= Masks[WhichConst][1];
214 Mask |= Masks[WhichConst][2];
216 Mask |= Masks[WhichConst][3];
220 if (
CallInst *CI = dyn_cast<CallInst>(Op0)) {
222 if (
F &&
F->getIntrinsicID() == Intrinsic::fabs) {
226 Op0 = CI->getArgOperand(0);
229 Worthy = WhichConst != 0;
230 PossibleJunk.insert(CI);
233 converted(&
I, Op0, Mask, Worthy);
236void SystemZTDCPass::convertICmp(
CmpInst &
I) {
237 Value *Op0 =
I.getOperand(0);
238 auto *
Const = dyn_cast<ConstantInt>(
I.getOperand(1));
239 auto Pred =
I.getPredicate();
243 if (
auto *Cast = dyn_cast<BitCastInst>(Op0)) {
245 if (!Cast->getSrcTy()->isFloatTy() &&
246 !Cast->getSrcTy()->isDoubleTy() &&
247 !Cast->getSrcTy()->isFP128Ty())
249 Value *
V = Cast->getOperand(0);
261 PossibleJunk.insert(Cast);
262 converted(&
I, V, Mask,
true);
263 }
else if (
auto *CI = dyn_cast<CallInst>(Op0)) {
266 if (!
F ||
F->getIntrinsicID() != Intrinsic::s390_tdc)
268 if (!
Const->isZero())
270 Value *
V = CI->getArgOperand(0);
271 auto *MaskC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
275 int Mask = MaskC->getZExtValue();
286 PossibleJunk.insert(CI);
287 converted(&
I, V, Mask,
false);
294 bool Worthy0, Worthy1;
295 std::tie(Op0, Mask0, Worthy0) = ConvertedInsts[cast<Instruction>(
I.getOperand(0))];
296 std::tie(Op1, Mask1, Worthy1) = ConvertedInsts[cast<Instruction>(
I.getOperand(1))];
300 switch (
I.getOpcode()) {
301 case Instruction::And:
302 Mask = Mask0 & Mask1;
304 case Instruction::Or:
305 Mask = Mask0 | Mask1;
307 case Instruction::Xor:
308 Mask = Mask0 ^ Mask1;
313 converted(&
I, Op0, Mask,
true);
316bool SystemZTDCPass::runOnFunction(
Function &
F) {
317 auto &TPC = getAnalysis<TargetPassConfig>();
323 ConvertedInsts.
clear();
324 LogicOpsWorklist.clear();
325 PossibleJunk.clear();
329 if (
I.getOpcode() == Instruction::FCmp)
330 convertFCmp(cast<CmpInst>(
I));
331 else if (
I.getOpcode() == Instruction::ICmp)
332 convertICmp(cast<CmpInst>(
I));
336 if (ConvertedInsts.
empty())
340 while (!LogicOpsWorklist.empty()) {
342 LogicOpsWorklist.pop_back();
345 if (ConvertedInsts.
count(dyn_cast<Instruction>(
Op->getOperand(0))) &&
346 ConvertedInsts.
count(dyn_cast<Instruction>(
Op->getOperand(1))) &&
355 auto &Ctx =
M.getContext();
357 bool MadeChange =
false;
358 for (
auto &It :
reverse(ConvertedInsts)) {
363 std::tie(V, Mask, Worthy) = It.second;
364 if (!
I->user_empty()) {
375 I->replaceAllUsesWith(ICmp);
378 I->eraseFromParent();
387 for (
auto *
I : PossibleJunk)
389 I->eraseFromParent();
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file implements a map that provides insertion order iteration.
Module.h This file contains the declarations for the Module class.
#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.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
This class represents a function call, abstracting a target machine's calling convention.
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)
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This class implements a map that also provides access to all stored values in a deterministic order.
size_type count(const KeyT &Key) const
A Module instance is used to store all the information related to an LLVM module.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Primary interface to the complete machine description for the target machine.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
Target-Independent Code Generator Pass Configuration Options.
const fltSemantics & getFltSemantics() const
static IntegerType * getInt1Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
LLVM Value Representation.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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
This is an optimization pass for GlobalISel generic memory operations.
auto reverse(ContainerTy &&C)
FunctionPass * createSystemZTDCPass()
void initializeSystemZTDCPassPass(PassRegistry &)