[PATCH] D103661: [IR] Add utility to convert constant expression operands (of an instruction) to instructions.

Mahesha S via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 6 00:00:24 PDT 2021


hsmhsm added a comment.

In D103661#2798554 <https://reviews.llvm.org/D103661#2798554>, @foad wrote:

> Given a constant expression tree that contains CE, you are converting the entire tree to instructions. That is overkill. You only need to convert the nodes on the path from CE to the root.

Strictly speaking, yes, I agree, but, this requires to explicitly enumerate all possible paths from root to CE (since CE can possbly appear as more than one node in the same tree), and convert nodes only in those enumerated paths into instructions (please take a look at example that I gave while replying to one of @rampitec comments below). I am not handling it yet. Let's see how to handle it.



================
Comment at: llvm/lib/IR/ReplaceConstant.cpp:107
+
+    if (CE->getNumOperands()) {
+      SmallPtrSet<Value *, 4> Operands2;
----------------
rampitec wrote:
> To address Jay's comment I think you can pass an original CE into this function and amend the if to only execute it if CE != ReplacedCE. It will then skip the operands of the expression being replaced itself. I.e.:
> 
> 
> ```
> @@ -77,12 +77,13 @@ void convertConstantExprsToInstructions(Instruction *I, ConstantExpr *CE,
> 
>    // Convert constant expressions operands of I (from the set CEOperands) to
>    // instructions.
> -  convertConstantExprsToInstructions(I, CEOperands, Insts);
> +  convertConstantExprsToInstructions(I, CEOperands, Insts, CE);
>  }
> 
>  void convertConstantExprsToInstructions(Instruction *I,
>                                          SmallPtrSetImpl<Value *> &Operands,
> -                                        SmallPtrSetImpl<Instruction *> &Insts) {
> +                                        SmallPtrSetImpl<Instruction *> &Insts,
> +                                        ConstantExpr *C) {
>    for (Use &U : I->operands()) {
>      auto *V = U.get();
> 
> @@ -104,11 +105,9 @@ void convertConstantExprsToInstructions(Instruction *I,
>      I->replaceUsesOfWith(CE, NI);
>      Insts.insert(NI);
> 
> -    if (CE->getNumOperands()) {
> +    if (C != CE && CE->getNumOperands()) {
>       SmallPtrSet<Value *, 4> Operands2;
>       for (Use &UU : CE->operands())
>         Operands2.insert(UU.get());
> -      convertConstantExprsToInstructions(NI, Operands2, Insts);
> +      convertConstantExprsToInstructions(NI, Operands2, Insts, C);
>      }
> 
>      CE->removeDeadConstantUsers();
> ```
> Note there are never recursive constant expressions.
This will some extent reduces the unnecessary CE to I conversion. But, does not fully handle what @foad is suggesting. Consider below tree. 

```
                                     I0
                                     |
                                    CE1
                                  /     \
                               CE2      CE3
                              /   \        \
                           CE4    CE4      CE5
                           /  \      \
                        CE6   CE6    CE7
                         /      \
                      CE8       CE9
```

Assuminng that, we need to convert CE4 into instructions, we only need to touch CEs in the two paths - (1) CE1, CE2, CE4 and (2) CE1, CE2, CE4.  So result would be something like below.

```
I4_2 (CE7)
I4_1 (CE6, CE6)
I2 (I4_1, I4_2)
I1 (I2,  CE3)
I0 (I1)
```

But, the above code that you are suggesting here will convert every sub-tree except sub-trees starting from CE4.

Let's see what to do about it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103661/new/

https://reviews.llvm.org/D103661



More information about the llvm-commits mailing list