[llvm] 42dba63 - [TypePromotion] Make TypeSize a class member

Sam Parker via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 24 02:05:17 PST 2019


Author: Sam Parker
Date: 2019-12-24T05:04:35-05:00
New Revision: 42dba633a3b3de73d8c27c409ff7414eb64cbc12

URL: https://github.com/llvm/llvm-project/commit/42dba633a3b3de73d8c27c409ff7414eb64cbc12
DIFF: https://github.com/llvm/llvm-project/commit/42dba633a3b3de73d8c27c409ff7414eb64cbc12.diff

LOG: [TypePromotion] Make TypeSize a class member

Having TypeSize as a static class variable was causing problems
with multi-threading. Several static functions have now been
converted into methods of TypePromotion and a few other members
of TypePromotion and IRPromoter have been added or removed.

Differential Revision: https://reviews.llvm.org/D71832

Added: 
    

Modified: 
    llvm/lib/CodeGen/TypePromotion.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/TypePromotion.cpp b/llvm/lib/CodeGen/TypePromotion.cpp
index 2dd037d2ccb0..cf4ce2eb5809 100644
--- a/llvm/lib/CodeGen/TypePromotion.cpp
+++ b/llvm/lib/CodeGen/TypePromotion.cpp
@@ -104,17 +104,14 @@ DisablePromotion("disable-type-promotion", cl::Hidden, cl::init(true),
 
 namespace {
 class IRPromoter {
+  LLVMContext &Ctx;
+  IntegerType *OrigTy = nullptr;
+  unsigned PromotedWidth = 0;
+  IntegerType *ExtTy = nullptr;
   SmallPtrSet<Value*, 8> NewInsts;
   SmallPtrSet<Instruction*, 4> InstsToRemove;
   DenseMap<Value*, SmallVector<Type*, 4>> TruncTysMap;
   SmallPtrSet<Value*, 8> Promoted;
-  LLVMContext &Ctx;
-  // The type we promote to: always i32
-  IntegerType *ExtTy = nullptr;
-  // The type of the value that the search began from, either i8 or i16.
-  // This defines the max range of the values that we allow in the promoted
-  // tree.
-  IntegerType *OrigTy = nullptr;
   SetVector<Value*> *Visited;
   SmallPtrSetImpl<Value*> *Sources;
   SmallPtrSetImpl<Instruction*> *Sinks;
@@ -130,11 +127,14 @@ class IRPromoter {
   void Cleanup(void);
 
 public:
-  IRPromoter(Module *M) : Ctx(M->getContext()) { }
-
+  IRPromoter(LLVMContext &C, IntegerType *Ty, unsigned Width) :
+    Ctx(C), OrigTy(Ty), PromotedWidth(Width) {
+    ExtTy = IntegerType::get(Ctx, PromotedWidth);
+    assert(OrigTy->getPrimitiveSizeInBits() < ExtTy->getPrimitiveSizeInBits()
+           && "Original type not smaller than extended type");
+  }
 
-  void Mutate(Type *OrigTy, unsigned PromotedWidth,
-              SetVector<Value*> &Visited,
+  void Mutate(SetVector<Value*> &Visited,
               SmallPtrSetImpl<Value*> &Sources,
               SmallPtrSetImpl<Instruction*> &Sinks,
               SmallPtrSetImpl<Instruction*> &SafeToPromote,
@@ -142,20 +142,43 @@ class IRPromoter {
 };
 
 class TypePromotion : public FunctionPass {
-  IRPromoter *Promoter = nullptr;
+  unsigned TypeSize = 0;
+  LLVMContext *Ctx = nullptr;
+  unsigned RegisterBitWidth = 0;
   SmallPtrSet<Value*, 16> AllVisited;
   SmallPtrSet<Instruction*, 8> SafeToPromote;
   SmallPtrSet<Instruction*, 4> SafeWrap;
 
+  // Does V have the same size result type as TypeSize.
+  bool EqualTypeSize(Value *V);
+  // Does V have the same size, or narrower, result type as TypeSize.
+  bool LessOrEqualTypeSize(Value *V);
+  // Does V have a result type that is wider than TypeSize.
+  bool GreaterThanTypeSize(Value *V);
+  // Does V have a result type that is narrower than TypeSize.
+  bool LessThanTypeSize(Value *V);
+  // Should V be a leaf in the promote tree?
+  bool isSource(Value *V);
+  // Should V be a root in the promotion tree?
+  bool isSink(Value *V);
+  // Should we change the result type of V? It will result in the users of V
+  // being visited.
+  bool shouldPromote(Value *V);
+  // Is I an add or a sub, which isn't marked as nuw, but where a wrapping
+  // result won't affect the computation?
   bool isSafeWrap(Instruction *I);
+  // Can V have its integer type promoted, or can the type be ignored.
+  bool isSupportedType(Value *V);
+  // Is V an instruction with a supported opcode or another value that we can
+  // handle, such as constants and basic blocks.
   bool isSupportedValue(Value *V);
+  // Is V an instruction thats result can trivially promoted, or has safe
+  // wrapping.
   bool isLegalToPromote(Value *V);
   bool TryToPromote(Value *V, unsigned PromotedWidth);
 
 public:
   static char ID;
-  static unsigned TypeSize;
-  Type *OrigTy = nullptr;
 
   TypePromotion() : FunctionPass(ID) {}
 
@@ -166,9 +189,7 @@ class TypePromotion : public FunctionPass {
 
   StringRef getPassName() const override { return PASS_NAME; }
 
-  bool doInitialization(Module &M) override;
   bool runOnFunction(Function &F) override;
-  bool doFinalization(Module &M) override;
 };
 
 }
@@ -182,41 +203,20 @@ static bool GenerateSignBits(Value *V) {
          Opc == Instruction::SRem || Opc == Instruction::SExt;
 }
 
-static bool EqualTypeSize(Value *V) {
-  return V->getType()->getScalarSizeInBits() == TypePromotion::TypeSize;
+bool TypePromotion::EqualTypeSize(Value *V) {
+  return V->getType()->getScalarSizeInBits() == TypeSize;
 }
 
-static bool LessOrEqualTypeSize(Value *V) {
-  return V->getType()->getScalarSizeInBits() <= TypePromotion::TypeSize;
+bool TypePromotion::LessOrEqualTypeSize(Value *V) {
+  return V->getType()->getScalarSizeInBits() <= TypeSize;
 }
 
-static bool GreaterThanTypeSize(Value *V) {
-  return V->getType()->getScalarSizeInBits() > TypePromotion::TypeSize;
+bool TypePromotion::GreaterThanTypeSize(Value *V) {
+  return V->getType()->getScalarSizeInBits() > TypeSize;
 }
 
-static bool LessThanTypeSize(Value *V) {
-  return V->getType()->getScalarSizeInBits() < TypePromotion::TypeSize;
-}
-
-/// Some instructions can use 8- and 16-bit operands, and we don't need to
-/// promote anything larger. We disallow booleans to make life easier when
-/// dealing with icmps but allow any other integer that is <= 16 bits. Void
-/// types are accepted so we can handle switches.
-static bool isSupportedType(Value *V) {
-  Type *Ty = V->getType();
-
-  // Allow voids and pointers, these won't be promoted.
-  if (Ty->isVoidTy() || Ty->isPointerTy())
-    return true;
-
-  if (auto *Ld = dyn_cast<LoadInst>(V))
-    Ty = cast<PointerType>(Ld->getPointerOperandType())->getElementType();
-
-  if (!isa<IntegerType>(Ty) ||
-      cast<IntegerType>(V->getType())->getBitWidth() == 1)
-    return false;
-
-  return LessOrEqualTypeSize(V);
+bool TypePromotion::LessThanTypeSize(Value *V) {
+  return V->getType()->getScalarSizeInBits() < TypeSize;
 }
 
 /// Return true if the given value is a source in the use-def chain, producing
@@ -226,7 +226,7 @@ static bool isSupportedType(Value *V) {
 /// return values because we only accept ones that guarantee a zeroext ret val.
 /// Many arguments will have the zeroext attribute too, so those would be free
 /// too.
-static bool isSource(Value *V) {
+bool TypePromotion::isSource(Value *V) {
   if (!isa<IntegerType>(V->getType()))
     return false;
 
@@ -247,7 +247,7 @@ static bool isSource(Value *V) {
 /// Return true if V will require any promoted values to be truncated for the
 /// the IR to remain valid. We can't mutate the value type of these
 /// instructions.
-static bool isSink(Value *V) {
+bool TypePromotion::isSink(Value *V) {
   // TODO The truncate also isn't actually necessary because we would already
   // proved that the data value is kept within the range of the original data
   // type.
@@ -380,12 +380,13 @@ bool TypePromotion::isSafeWrap(Instruction *I) {
   } else if (Total.ugt(Max))
     return false;
 
-  LLVM_DEBUG(dbgs() << "IR Promotion: Allowing safe overflow for " << *I << "\n");
+  LLVM_DEBUG(dbgs() << "IR Promotion: Allowing safe overflow for "
+             << *I << "\n");
   SafeWrap.insert(I);
   return true;
 }
 
-static bool shouldPromote(Value *V) {
+bool TypePromotion::shouldPromote(Value *V) {
   if (!isa<IntegerType>(V->getType()) || isSink(V))
     return false;
 
@@ -540,7 +541,8 @@ void IRPromoter::PromoteTree() {
         I->setOperand(i, UndefValue::get(ExtTy));
     }
 
-    if (shouldPromote(I)) {
+    // Mutate the result type, unless this is an icmp.
+    if (!isa<ICmpInst>(I)) {
       I->mutateType(ExtTy);
       Promoted.insert(I);
     }
@@ -644,13 +646,6 @@ void IRPromoter::Cleanup() {
     I->dropAllReferences();
     I->eraseFromParent();
   }
-
-  InstsToRemove.clear();
-  NewInsts.clear();
-  TruncTysMap.clear();
-  Promoted.clear();
-  SafeToPromote->clear();
-  SafeWrap->clear();
 }
 
 void IRPromoter::ConvertTruncs() {
@@ -678,21 +673,13 @@ void IRPromoter::ConvertTruncs() {
   }
 }
 
-void IRPromoter::Mutate(Type *OrigTy, unsigned PromotedWidth,
-                        SetVector<Value*> &Visited,
+void IRPromoter::Mutate(SetVector<Value*> &Visited,
                         SmallPtrSetImpl<Value*> &Sources,
                         SmallPtrSetImpl<Instruction*> &Sinks,
                         SmallPtrSetImpl<Instruction*> &SafeToPromote,
                         SmallPtrSetImpl<Instruction*> &SafeWrap) {
   LLVM_DEBUG(dbgs() << "IR Promotion: Promoting use-def chains from "
-             << TypePromotion::TypeSize << " to " << PromotedWidth
-             << "-bits\n");
-
-  assert(isa<IntegerType>(OrigTy) && "expected integer type");
-  this->OrigTy = cast<IntegerType>(OrigTy);
-  ExtTy = IntegerType::get(Ctx, PromotedWidth);
-  assert(OrigTy->getPrimitiveSizeInBits() < ExtTy->getPrimitiveSizeInBits() &&
-         "original type not smaller than extended type");
+             << OrigTy->getBitWidth() << " to " << PromotedWidth << "-bits\n");
 
   this->Visited = &Visited;
   this->Sources = &Sources;
@@ -744,6 +731,24 @@ void IRPromoter::Mutate(Type *OrigTy, unsigned PromotedWidth,
   LLVM_DEBUG(dbgs() << "IR Promotion: Mutation complete\n");
 }
 
+/// We disallow booleans to make life easier when dealing with icmps but allow
+/// any other integer that fits in a scalar register. Void types are accepted
+/// so we can handle switches.
+bool TypePromotion::isSupportedType(Value *V) {
+  Type *Ty = V->getType();
+
+  // Allow voids and pointers, these won't be promoted.
+  if (Ty->isVoidTy() || Ty->isPointerTy())
+    return true;
+
+  if (!isa<IntegerType>(Ty) ||
+      cast<IntegerType>(Ty)->getBitWidth() == 1 ||
+      cast<IntegerType>(Ty)->getBitWidth() > RegisterBitWidth)
+    return false;
+
+  return LessOrEqualTypeSize(V);
+}
+
 /// We accept most instructions, as well as Arguments and ConstantInsts. We
 /// Disallow casts other than zext and truncs and only allow calls if their
 /// return value is zeroext. We don't allow opcodes that can introduce sign
@@ -813,7 +818,7 @@ bool TypePromotion::isLegalToPromote(Value *V) {
 }
 
 bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth) {
-  OrigTy = V->getType();
+  Type *OrigTy = V->getType();
   TypeSize = OrigTy->getPrimitiveSizeInBits();
   SafeToPromote.clear();
   SafeWrap.clear();
@@ -903,28 +908,39 @@ bool TypePromotion::TryToPromote(Value *V, unsigned PromotedWidth) {
              for (auto *I : CurrentVisited)
                I->dump();
              );
+
   unsigned ToPromote = 0;
+  unsigned NonFreeArgs = 0;
+  SmallPtrSet<BasicBlock*, 4> Blocks;
   for (auto *V : CurrentVisited) {
-    if (Sources.count(V))
+    if (auto *I = dyn_cast<Instruction>(V))
+      Blocks.insert(I->getParent());
+
+    if (Sources.count(V)) {
+      if (auto *Arg = dyn_cast<Argument>(V))
+        if (!Arg->hasZExtAttr() && !Arg->hasSExtAttr())
+          ++NonFreeArgs;
       continue;
+    }
+
     if (Sinks.count(cast<Instruction>(V)))
       continue;
-    ++ToPromote;
-  }
+     ++ToPromote;
+   }
+
+  // DAG optimisations should be able to handle these cases better, especially
+  // for function arguments.
+  if (ToPromote < 2 || (Blocks.size() == 1 && (NonFreeArgs > SafeWrap.size())))
+    return false;
 
   if (ToPromote < 2)
     return false;
 
-  Promoter->Mutate(OrigTy, PromotedWidth, CurrentVisited, Sources, Sinks,
-                   SafeToPromote, SafeWrap);
+  IRPromoter Promoter(*Ctx, cast<IntegerType>(OrigTy), PromotedWidth);
+  Promoter.Mutate(CurrentVisited, Sources, Sinks, SafeToPromote, SafeWrap);
   return true;
 }
 
-bool TypePromotion::doInitialization(Module &M) {
-  Promoter = new IRPromoter(&M);
-  return false;
-}
-
 bool TypePromotion::runOnFunction(Function &F) {
   if (skipFunction(F) || DisablePromotion)
     return false;
@@ -942,11 +958,12 @@ bool TypePromotion::runOnFunction(Function &F) {
   const TargetLowering *TLI = SubtargetInfo->getTargetLowering();
   const TargetTransformInfo &TII =
     getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+  RegisterBitWidth = TII.getRegisterBitWidth(false);
+  Ctx = &F.getParent()->getContext();
 
   // Search up from icmps to try to promote their operands.
   for (BasicBlock &BB : F) {
-    auto &Insts = BB.getInstList();
-    for (auto &I : Insts) {
+    for (auto &I : BB) {
       if (AllVisited.count(&I))
         continue;
 
@@ -972,7 +989,7 @@ bool TypePromotion::runOnFunction(Function &F) {
             break;
 
           EVT PromotedVT = TLI->getTypeToTransformTo(ICmp->getContext(), SrcVT);
-          if (TII.getRegisterBitWidth(false) < PromotedVT.getSizeInBits()) {
+          if (RegisterBitWidth < PromotedVT.getSizeInBits()) {
             LLVM_DEBUG(dbgs() << "IR Promotion: Couldn't find target register "
                        << "for promoted type\n");
             break;
@@ -994,16 +1011,10 @@ bool TypePromotion::runOnFunction(Function &F) {
   return MadeChange;
 }
 
-bool TypePromotion::doFinalization(Module &M) {
-  delete Promoter;
-  return false;
-}
-
 INITIALIZE_PASS_BEGIN(TypePromotion, DEBUG_TYPE, PASS_NAME, false, false)
 INITIALIZE_PASS_END(TypePromotion, DEBUG_TYPE, PASS_NAME, false, false)
 
 char TypePromotion::ID = 0;
-unsigned TypePromotion::TypeSize = 0;
 
 FunctionPass *llvm::createTypePromotionPass() {
   return new TypePromotion();


        


More information about the llvm-commits mailing list