Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //====- TargetFolder.h - Constant folding helper ---------------*- C++ -*-====//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the TargetFolder class, a helper for IRBuilder.
  10. // It provides IRBuilder with a set of methods for creating constants with
  11. // target dependent folding, in addition to the same target-independent
  12. // folding that the ConstantFolder class provides.  For general constant
  13. // creation and folding, use ConstantExpr and the routines in
  14. // llvm/Analysis/ConstantFolding.h.
  15. //
  16. //===----------------------------------------------------------------------===//
  17.  
  18. #ifndef LLVM_ANALYSIS_TARGETFOLDER_H
  19. #define LLVM_ANALYSIS_TARGETFOLDER_H
  20.  
  21. #include "llvm/ADT/ArrayRef.h"
  22. #include "llvm/Analysis/ConstantFolding.h"
  23. #include "llvm/IR/Constants.h"
  24. #include "llvm/IR/IRBuilderFolder.h"
  25. #include "llvm/IR/Operator.h"
  26.  
  27. namespace llvm {
  28.  
  29. class Constant;
  30. class DataLayout;
  31. class Type;
  32.  
  33. /// TargetFolder - Create constants with target dependent folding.
  34. class TargetFolder final : public IRBuilderFolder {
  35.   const DataLayout &DL;
  36.  
  37.   /// Fold - Fold the constant using target specific information.
  38.   Constant *Fold(Constant *C) const {
  39.     return ConstantFoldConstant(C, DL);
  40.   }
  41.  
  42.   virtual void anchor();
  43.  
  44. public:
  45.   explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
  46.  
  47.   //===--------------------------------------------------------------------===//
  48.   // Value-based folders.
  49.   //
  50.   // Return an existing value or a constant if the operation can be simplified.
  51.   // Otherwise return nullptr.
  52.   //===--------------------------------------------------------------------===//
  53.  
  54.   Value *FoldBinOp(Instruction::BinaryOps Opc, Value *LHS,
  55.                    Value *RHS) const override {
  56.     auto *LC = dyn_cast<Constant>(LHS);
  57.     auto *RC = dyn_cast<Constant>(RHS);
  58.     if (LC && RC) {
  59.       if (ConstantExpr::isDesirableBinOp(Opc))
  60.         return Fold(ConstantExpr::get(Opc, LC, RC));
  61.       return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
  62.     }
  63.     return nullptr;
  64.   }
  65.  
  66.   Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
  67.                         bool IsExact) const override {
  68.     auto *LC = dyn_cast<Constant>(LHS);
  69.     auto *RC = dyn_cast<Constant>(RHS);
  70.     if (LC && RC) {
  71.       if (ConstantExpr::isDesirableBinOp(Opc))
  72.         return Fold(ConstantExpr::get(
  73.             Opc, LC, RC, IsExact ? PossiblyExactOperator::IsExact : 0));
  74.       return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
  75.     }
  76.     return nullptr;
  77.   }
  78.  
  79.   Value *FoldNoWrapBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
  80.                          bool HasNUW, bool HasNSW) const override {
  81.     auto *LC = dyn_cast<Constant>(LHS);
  82.     auto *RC = dyn_cast<Constant>(RHS);
  83.     if (LC && RC) {
  84.       if (ConstantExpr::isDesirableBinOp(Opc)) {
  85.         unsigned Flags = 0;
  86.         if (HasNUW)
  87.           Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
  88.         if (HasNSW)
  89.           Flags |= OverflowingBinaryOperator::NoSignedWrap;
  90.         return Fold(ConstantExpr::get(Opc, LC, RC, Flags));
  91.       }
  92.       return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
  93.     }
  94.     return nullptr;
  95.   }
  96.  
  97.   Value *FoldBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
  98.                       FastMathFlags FMF) const override {
  99.     return FoldBinOp(Opc, LHS, RHS);
  100.   }
  101.  
  102.   Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
  103.     auto *LC = dyn_cast<Constant>(LHS);
  104.     auto *RC = dyn_cast<Constant>(RHS);
  105.     if (LC && RC)
  106.       return Fold(ConstantExpr::getCompare(P, LC, RC));
  107.     return nullptr;
  108.   }
  109.  
  110.   Value *FoldUnOpFMF(Instruction::UnaryOps Opc, Value *V,
  111.                       FastMathFlags FMF) const override {
  112.     if (Constant *C = dyn_cast<Constant>(V))
  113.       return ConstantFoldUnaryOpOperand(Opc, C, DL);
  114.     return nullptr;
  115.   }
  116.  
  117.   Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
  118.                  bool IsInBounds = false) const override {
  119.     if (auto *PC = dyn_cast<Constant>(Ptr)) {
  120.       // Every index must be constant.
  121.       if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
  122.         return nullptr;
  123.       if (IsInBounds)
  124.         return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList));
  125.       else
  126.         return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList));
  127.     }
  128.     return nullptr;
  129.   }
  130.  
  131.   Value *FoldSelect(Value *C, Value *True, Value *False) const override {
  132.     auto *CC = dyn_cast<Constant>(C);
  133.     auto *TC = dyn_cast<Constant>(True);
  134.     auto *FC = dyn_cast<Constant>(False);
  135.     if (CC && TC && FC)
  136.       return Fold(ConstantExpr::getSelect(CC, TC, FC));
  137.  
  138.     return nullptr;
  139.   }
  140.  
  141.   Value *FoldExtractValue(Value *Agg,
  142.                           ArrayRef<unsigned> IdxList) const override {
  143.     if (auto *CAgg = dyn_cast<Constant>(Agg))
  144.       return ConstantFoldExtractValueInstruction(CAgg, IdxList);
  145.     return nullptr;
  146.   };
  147.  
  148.   Value *FoldInsertValue(Value *Agg, Value *Val,
  149.                          ArrayRef<unsigned> IdxList) const override {
  150.     auto *CAgg = dyn_cast<Constant>(Agg);
  151.     auto *CVal = dyn_cast<Constant>(Val);
  152.     if (CAgg && CVal)
  153.       return ConstantFoldInsertValueInstruction(CAgg, CVal, IdxList);
  154.     return nullptr;
  155.   }
  156.  
  157.   Value *FoldExtractElement(Value *Vec, Value *Idx) const override {
  158.     auto *CVec = dyn_cast<Constant>(Vec);
  159.     auto *CIdx = dyn_cast<Constant>(Idx);
  160.     if (CVec && CIdx)
  161.       return Fold(ConstantExpr::getExtractElement(CVec, CIdx));
  162.     return nullptr;
  163.   }
  164.  
  165.   Value *FoldInsertElement(Value *Vec, Value *NewElt,
  166.                            Value *Idx) const override {
  167.     auto *CVec = dyn_cast<Constant>(Vec);
  168.     auto *CNewElt = dyn_cast<Constant>(NewElt);
  169.     auto *CIdx = dyn_cast<Constant>(Idx);
  170.     if (CVec && CNewElt && CIdx)
  171.       return Fold(ConstantExpr::getInsertElement(CVec, CNewElt, CIdx));
  172.     return nullptr;
  173.   }
  174.  
  175.   Value *FoldShuffleVector(Value *V1, Value *V2,
  176.                            ArrayRef<int> Mask) const override {
  177.     auto *C1 = dyn_cast<Constant>(V1);
  178.     auto *C2 = dyn_cast<Constant>(V2);
  179.     if (C1 && C2)
  180.       return Fold(ConstantExpr::getShuffleVector(C1, C2, Mask));
  181.     return nullptr;
  182.   }
  183.  
  184.   //===--------------------------------------------------------------------===//
  185.   // Cast/Conversion Operators
  186.   //===--------------------------------------------------------------------===//
  187.  
  188.   Constant *CreateCast(Instruction::CastOps Op, Constant *C,
  189.                        Type *DestTy) const override {
  190.     if (C->getType() == DestTy)
  191.       return C; // avoid calling Fold
  192.     return Fold(ConstantExpr::getCast(Op, C, DestTy));
  193.   }
  194.   Constant *CreateIntCast(Constant *C, Type *DestTy,
  195.                           bool isSigned) const override {
  196.     if (C->getType() == DestTy)
  197.       return C; // avoid calling Fold
  198.     return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
  199.   }
  200.   Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
  201.     if (C->getType() == DestTy)
  202.       return C; // avoid calling Fold
  203.     return Fold(ConstantExpr::getPointerCast(C, DestTy));
  204.   }
  205.   Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
  206.     if (C->getType() == DestTy)
  207.       return C; // avoid calling Fold
  208.     return Fold(ConstantExpr::getFPCast(C, DestTy));
  209.   }
  210.   Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
  211.     return CreateCast(Instruction::BitCast, C, DestTy);
  212.   }
  213.   Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
  214.     return CreateCast(Instruction::IntToPtr, C, DestTy);
  215.   }
  216.   Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
  217.     return CreateCast(Instruction::PtrToInt, C, DestTy);
  218.   }
  219.   Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
  220.     if (C->getType() == DestTy)
  221.       return C; // avoid calling Fold
  222.     return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
  223.   }
  224.   Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
  225.     if (C->getType() == DestTy)
  226.       return C; // avoid calling Fold
  227.     return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
  228.   }
  229.   Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
  230.     if (C->getType() == DestTy)
  231.       return C; // avoid calling Fold
  232.     return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
  233.   }
  234.  
  235.   Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
  236.                                                 Type *DestTy) const override {
  237.     if (C->getType() == DestTy)
  238.       return C; // avoid calling Fold
  239.     return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
  240.   }
  241.  
  242.   //===--------------------------------------------------------------------===//
  243.   // Compare Instructions
  244.   //===--------------------------------------------------------------------===//
  245.  
  246.   Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
  247.                        Constant *RHS) const override {
  248.     return Fold(ConstantExpr::getCompare(P, LHS, RHS));
  249.   }
  250. };
  251.  
  252. }
  253.  
  254. #endif
  255.