Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

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