Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NFC][RemoveDIs] Have CreateNeg only accept iterators, template for other patches #82999

Merged
merged 2 commits into from
Feb 29, 2024

Conversation

jmorse
Copy link
Member

@jmorse jmorse commented Feb 26, 2024

Removing debug-intrinsics requires that we always insert with an iterator, not with an instruction position. To enforce that, we need to eliminate the Instruction * taking functions. It's safe to leave the insert-at-end-of-block functions as the intention is clear for debug info purposes (i.e., insert after both instructions and debug-info at the end of the function).

This patch demonstrates how that needs to happen. At a variety of call-sites to the CreateNeg constructor we need to consider:

  • Has this instruction been selected because of the operation it performs? In that case, just call getIterator and pass an iterator in.
  • Has this instruction been selected because of it's position? If so, we need to keep the iterator identifying that position (see the 3rd hunk changing Reassociate.cpp, although it's coincidentally not debug-info significant).

This also demonstrates what we'll try and do with the constructor methods going forwards: have one fully explicit set of parameters including iterator, and another with default-arguments where the block-to-insert-into argument defaults to nullptr / no-position, creating an instruction that hasn't been inserted yet. We could try and have an optional iterator with a default of std::nullopt, IMO that's un-necessarily fiddly.

That involves deleting an assertion that you're not inserting into a nullptr block. IMO this is isn't ideal but is OK: you can already accidentally create-without-insertion with an unexpectedly null instruction pointer variable, this expands it to having an unexpectedly null block pointer variable. The assertion failure just happens sometime later.

Removing debug-intrinsics requires that we always insert with an iterator;
this patch demonstrates how that needs to happen. At a variety of
call-sites to the CreateNeg constructor we need to consider:
 * Has this instruction been selected because of the operation it performs?
   In that case, just call getIterator and pass an iterator in.
 * Has this instruction been selected because of it's position? If so, we
   need to keep the iterator identifying that position (see the 3rd hunk
   changing Reassociate.cpp).

This also demonstrates what we'll try and do with the constructor methods:
have one fully explicit set of parameters, and another where the last
position argument defaults to nullptr / no-position, creating an
instruction that hasn't been inserted yet.
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 26, 2024

@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-llvm-transforms

Author: Jeremy Morse (jmorse)

Changes

Removing debug-intrinsics requires that we always insert with an iterator, not with an instruction position. To enforce that, we need to eliminate the Instruction * taking functions. It's safe to leave the insert-at-end-of-block functions as the intention is clear for debug info purposes (i.e., insert after both instructions and debug-info at the end of the function).

This patch demonstrates how that needs to happen. At a variety of call-sites to the CreateNeg constructor we need to consider:

  • Has this instruction been selected because of the operation it performs? In that case, just call getIterator and pass an iterator in.
  • Has this instruction been selected because of it's position? If so, we need to keep the iterator identifying that position (see the 3rd hunk changing Reassociate.cpp, although it's coincidentally not debug-info significant).

This also demonstrates what we'll try and do with the constructor methods going forwards: have one fully explicit set of parameters including iterator, and another with default-arguments where the block-to-insert-into argument defaults to nullptr / no-position, creating an instruction that hasn't been inserted yet. We could try and have an optional iterator with a default of std::nullopt, IMO that's un-necessarily fiddly.

That involves deleting an assertion that you're not inserting into a nullptr block. IMO this is isn't ideal but is OK: you can already accidentally create-without-insertion with an unexpectedly null instruction pointer variable, this expands it to having an unexpectedly null block pointer variable. The assertion failure just happens sometime later.


Full diff: https://github.com/llvm/llvm-project/pull/82999.diff

5 Files Affected:

  • (modified) llvm/include/llvm/IR/InstrTypes.h (+1-3)
  • (modified) llvm/lib/IR/Instruction.cpp (+3-3)
  • (modified) llvm/lib/IR/Instructions.cpp (-8)
  • (modified) llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp (+4-4)
  • (modified) llvm/lib/Transforms/Scalar/Reassociate.cpp (+3-3)
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 4ee51cd192ed7c..a124fbb88e3bcd 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -468,9 +468,7 @@ class BinaryOperator : public Instruction {
   static BinaryOperator *CreateNeg(Value *Op, const Twine &Name,
                                    BasicBlock::iterator InsertBefore);
   static BinaryOperator *CreateNeg(Value *Op, const Twine &Name = "",
-                                   Instruction *InsertBefore = nullptr);
-  static BinaryOperator *CreateNeg(Value *Op, const Twine &Name,
-                                   BasicBlock *InsertAtEnd);
+                                   BasicBlock *InsertAtEnd = nullptr);
   static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name,
                                       BasicBlock::iterator InsertBefore);
   static BinaryOperator *CreateNSWNeg(Value *Op, const Twine &Name = "",
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index c54f8d7aca4a96..95f198b012224b 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -48,9 +48,9 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
                          BasicBlock *InsertAtEnd)
   : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
 
-  // append this instruction into the basic block
-  assert(InsertAtEnd && "Basic block to append to may not be NULL!");
-  insertInto(InsertAtEnd, InsertAtEnd->end());
+  // If requested, append this instruction into the basic block.
+  if (InsertAtEnd)
+    insertInto(InsertAtEnd, InsertAtEnd->end());
 }
 
 Instruction::~Instruction() {
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 25778570ebf34a..976015656a5f96 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -3245,14 +3245,6 @@ BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name,
                             InsertBefore);
 }
 
-BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name,
-                                          Instruction *InsertBefore) {
-  Value *Zero = ConstantInt::get(Op->getType(), 0);
-  return new BinaryOperator(Instruction::Sub,
-                            Zero, Op,
-                            Op->getType(), Name, InsertBefore);
-}
-
 BinaryOperator *BinaryOperator::CreateNeg(Value *Op, const Twine &Name,
                                           BasicBlock *InsertAtEnd) {
   Value *Zero = ConstantInt::get(Op->getType(), 0);
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 6ce9eb3656c93a..3f1bf2f858ac23 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -906,7 +906,7 @@ static bool processSRem(BinaryOperator *SDI, const ConstantRange &LCR,
     if (Op.D == Domain::NonNegative)
       continue;
     auto *BO =
-        BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI);
+        BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI->getIterator());
     BO->setDebugLoc(SDI->getDebugLoc());
     Op.V = BO;
   }
@@ -919,7 +919,7 @@ static bool processSRem(BinaryOperator *SDI, const ConstantRange &LCR,
 
   // If the divident was non-positive, we need to negate the result.
   if (Ops[0].D == Domain::NonPositive) {
-    Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI);
+    Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI->getIterator());
     Res->setDebugLoc(SDI->getDebugLoc());
   }
 
@@ -967,7 +967,7 @@ static bool processSDiv(BinaryOperator *SDI, const ConstantRange &LCR,
     if (Op.D == Domain::NonNegative)
       continue;
     auto *BO =
-        BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI);
+        BinaryOperator::CreateNeg(Op.V, Op.V->getName() + ".nonneg", SDI->getIterator());
     BO->setDebugLoc(SDI->getDebugLoc());
     Op.V = BO;
   }
@@ -981,7 +981,7 @@ static bool processSDiv(BinaryOperator *SDI, const ConstantRange &LCR,
 
   // If the operands had two different domains, we need to negate the result.
   if (Ops[0].D != Ops[1].D) {
-    Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI);
+    Res = BinaryOperator::CreateNeg(Res, Res->getName() + ".neg", SDI->getIterator());
     Res->setDebugLoc(SDI->getDebugLoc());
   }
 
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index 818c7b40d489ef..11fb70090b1972 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -270,7 +270,7 @@ static BinaryOperator *CreateMul(Value *S1, Value *S2, const Twine &Name,
 }
 
 static Instruction *CreateNeg(Value *S1, const Twine &Name,
-                              Instruction *InsertBefore, Value *FlagsOp) {
+                              BasicBlock::iterator InsertBefore, Value *FlagsOp) {
   if (S1->getType()->isIntOrIntVectorTy())
     return BinaryOperator::CreateNeg(S1, Name, InsertBefore);
 
@@ -958,7 +958,7 @@ static Value *NegateValue(Value *V, Instruction *BI,
 
   // Insert a 'neg' instruction that subtracts the value from zero to get the
   // negation.
-  Instruction *NewNeg = CreateNeg(V, V->getName() + ".neg", BI, BI);
+  Instruction *NewNeg = CreateNeg(V, V->getName() + ".neg", BI->getIterator(), BI);
   ToRedo.insert(NewNeg);
   return NewNeg;
 }
@@ -1246,7 +1246,7 @@ Value *ReassociatePass::RemoveFactorFromExpression(Value *V, Value *Factor) {
   }
 
   if (NeedsNegate)
-    V = CreateNeg(V, "neg", &*InsertPt, BO);
+    V = CreateNeg(V, "neg", InsertPt, BO);
 
   return V;
 }

Copy link

github-actions bot commented Feb 26, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Comment on lines 272 to 275
static Instruction *CreateNeg(Value *S1, const Twine &Name,
Instruction *InsertBefore, Value *FlagsOp) {
BasicBlock::iterator InsertBefore, Value *FlagsOp) {
if (S1->getType()->isIntOrIntVectorTy())
return BinaryOperator::CreateNeg(S1, Name, InsertBefore);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like I missed adding the definition of the iterator-taking CreateNeg in 76dd4bc, hence this presents in the diff as the argument-type changing instead of the deletion of the Instruction * taking function. That's my bad; but shouldn't be the same for the other scenarios where the Instruction * taking functions get removed.

Copy link
Contributor

@SLTozer SLTozer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems simple enough! (Clang-format required though)

@jmorse jmorse merged commit 7e88d51 into llvm:main Feb 29, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants