[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for SwitchStmt (PR #113112)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/113112

>From ec05cc37e1177f06c9a44a1e39dadc9306cc5c68 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Mon, 21 Oct 2024 08:09:31 +0900
Subject: [PATCH 1/2] [Coverage][Single] Enable Branch coverage for SwitchStmt

---
 clang/lib/CodeGen/CGStmt.cpp  | 12 ++
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 22 ++-
 .../CoverageMapping/single-byte-counters.cpp  | 13 ++-
 3 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index dbc1ce9bf993cd..80fe5cf183de16 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2259,6 +2259,18 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt 
&S) {
 
   ConditionScope.ForceCleanup();
 
+  // Close the last case (or DefaultBlock).
+  EmitBranch(SwitchExit.getBlock());
+
+  // Insert a False Counter if SwitchStmt doesn't have DefaultStmt.
+  if (getIsCounterPair(S.getCond()).second) {
+auto *ImplicitDefaultBlock = createBasicBlock("sw.false");
+EmitBlock(ImplicitDefaultBlock);
+incrementProfileCounter(true, S.getCond());
+Builder.CreateBr(SwitchInsn->getDefaultDest());
+SwitchInsn->setDefaultDest(ImplicitDefaultBlock);
+  }
+
   // Emit continuation.
   EmitBlock(SwitchExit.getBlock(), true);
   incrementProfileCounter(&S);
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index a331d5bc68286b..c5fdf23299e4e9 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -958,6 +958,14 @@ struct CounterCoverageMappingBuilder
 return {ExecCnt, SkipCnt};
   }
 
+  Counter getSwitchImplicitDefaultCounter(const Stmt *Cond, Counter 
ParentCount,
+  Counter CaseCountSum) {
+return (
+llvm::EnableSingleByteCoverage
+? Counter::getCounter(CounterMap[Cond].second = NextCounterNum++)
+: subtractCounters(ParentCount, CaseCountSum));
+  }
+
   bool IsCounterEqual(Counter OutCount, Counter ParentCount) {
 if (OutCount == ParentCount)
   return true;
@@ -1885,7 +1893,7 @@ struct CounterCoverageMappingBuilder
   propagateCounts(Counter::getZero(), Body);
 BreakContinue BC = BreakContinueStack.pop_back_val();
 
-if (!BreakContinueStack.empty() && !llvm::EnableSingleByteCoverage)
+if (!BreakContinueStack.empty())
   BreakContinueStack.back().ContinueCount = addCounters(
   BreakContinueStack.back().ContinueCount, BC.ContinueCount);
 
@@ -1900,11 +1908,6 @@ struct CounterCoverageMappingBuilder
 MostRecentLocation = getStart(S);
 handleFileExit(ExitLoc);
 
-// When single byte coverage mode is enabled, do not create branch region 
by
-// early returning.
-if (llvm::EnableSingleByteCoverage)
-  return;
-
 // Create a Branch Region around each Case. Subtract the case's
 // counter from the Parent counter to track the "False" branch count.
 Counter CaseCountSum;
@@ -1920,7 +1923,8 @@ struct CounterCoverageMappingBuilder
 // the hidden branch, which will be added later by the CodeGen. This region
 // will be associated with the switch statement's condition.
 if (!HasDefaultCase) {
-  Counter DefaultCount = subtractCounters(ParentCount, CaseCountSum);
+  Counter DefaultCount = getSwitchImplicitDefaultCounter(
+  S->getCond(), ParentCount, CaseCountSum);
   createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount);
 }
   }
@@ -1929,9 +1933,7 @@ struct CounterCoverageMappingBuilder
 extendRegion(S);
 
 SourceMappingRegion &Parent = getRegion();
-Counter Count = llvm::EnableSingleByteCoverage
-? getRegionCounter(S)
-: addCounters(Parent.getCounter(), 
getRegionCounter(S));
+Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
 
 // Reuse the existing region if it starts at our label. This is typical of
 // the first case in a switch.
diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp 
b/clang/test/CoverageMapping/single-byte-counters.cpp
index d20b695bc2636a..464fa370d86f09 100644
--- a/clang/test/CoverageMapping/single-byte-counters.cpp
+++ b/clang/test/CoverageMapping/single-byte-counters.cpp
@@ -34,19 +34,22 @@ int testIfElseReturn(int x) { // CHECK-NEXT: File 0, 
[[@LINE]]:29 -> [[@LINE+9]]
 }
 
 // CHECK-NEXT: testSwitch
-int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 
= [[C30:#0]]
+int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+20]]:2 
= [[C30:#0]]
   int result;
   switch (x) {
-// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> 
[[@LINE+10]]:15 = 0
-  case 1:   // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = 
[[C31:#2]]
+// CHECK-NEXT: Gap,File 

[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for IfStmt (PR #113111)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/113111

>From 3ea6383e2142889550f37389dfaaee81e5ae7d9c Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 20 Oct 2024 15:15:03 +0900
Subject: [PATCH 1/2] [Coverage][Single] Enable Branch coverage for IfStmt

---
 clang/lib/CodeGen/CGStmt.cpp  | 31 +++-
 clang/lib/CodeGen/CodeGenPGO.cpp  | 12 ---
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 21 +++
 .../CoverageMapping/single-byte-counters.cpp  | 36 ++-
 4 files changed, 38 insertions(+), 62 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index dbc1ce9bf993cd..c511e5f4f4213a 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -840,8 +840,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
 // If the skipped block has no labels in it, just emit the executed block.
 // This avoids emitting dead code and simplifies the CFG substantially.
 if (S.isConstexpr() || !ContainsLabel(Skipped)) {
-  if (CondConstant)
-incrementProfileCounter(&S);
+  incrementProfileCounter(!CondConstant, &S, true);
   if (Executed) {
 RunCleanupsScope ExecutedScope(*this);
 EmitStmt(Executed);
@@ -851,14 +850,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
 }
   }
 
+  auto HasSkip = getIsCounterPair(&S);
+
   // Otherwise, the condition did not fold, or we couldn't elide it.  Just emit
   // the conditional branch.
   llvm::BasicBlock *ThenBlock = createBasicBlock("if.then");
   llvm::BasicBlock *ContBlock = createBasicBlock("if.end");
-  llvm::BasicBlock *ElseBlock = ContBlock;
-  if (Else)
-ElseBlock = createBasicBlock("if.else");
-
+  llvm::BasicBlock *ElseBlock =
+  (Else || HasSkip.second ? createBasicBlock("if.else") : ContBlock);
   // Prefer the PGO based weights over the likelihood attribute.
   // When the build isn't optimized the metadata isn't used, so don't generate
   // it.
@@ -891,10 +890,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
 
   // Emit the 'then' code.
   EmitBlock(ThenBlock);
-  if (llvm::EnableSingleByteCoverage)
-incrementProfileCounter(S.getThen());
-  else
-incrementProfileCounter(&S);
+  incrementProfileCounter(false, &S);
   {
 RunCleanupsScope ThenScope(*this);
 EmitStmt(S.getThen());
@@ -908,9 +904,9 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
   auto NL = ApplyDebugLocation::CreateEmpty(*this);
   EmitBlock(ElseBlock);
 }
-// When single byte coverage mode is enabled, add a counter to else block.
-if (llvm::EnableSingleByteCoverage)
-  incrementProfileCounter(Else);
+// Add a counter to else block unless it has CounterExpr.
+if (HasSkip.second)
+  incrementProfileCounter(true, &S);
 {
   RunCleanupsScope ElseScope(*this);
   EmitStmt(Else);
@@ -920,15 +916,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
   auto NL = ApplyDebugLocation::CreateEmpty(*this);
   EmitBranch(ContBlock);
 }
+  } else if (HasSkip.second) {
+EmitBlock(ElseBlock);
+incrementProfileCounter(true, &S);
+EmitBranch(ContBlock);
   }
 
   // Emit the continuation block for code after the if.
   EmitBlock(ContBlock, true);
-
-  // When single byte coverage mode is enabled, add a counter to continuation
-  // block.
-  if (llvm::EnableSingleByteCoverage)
-incrementProfileCounter(&S);
 }
 
 bool CodeGenFunction::checkIfLoopMustProgress(const Expr 
*ControllingExpression,
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 0f2090da47a374..f6b9b5c82952c4 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -366,18 +366,6 @@ struct MapRegionCounters : public 
RecursiveASTVisitor {
 if (Hash.getHashVersion() == PGO_HASH_V1)
   return Base::TraverseIfStmt(If);
 
-// When single byte coverage mode is enabled, add a counter to then and
-// else.
-bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
-for (Stmt *CS : If->children()) {
-  if (!CS || NoSingleByteCoverage)
-continue;
-  if (CS == If->getThen())
-CounterMap[If->getThen()] = NextCounter++;
-  else if (CS == If->getElse())
-CounterMap[If->getElse()] = NextCounter++;
-}
-
 // Otherwise, keep track of which branch we're in while traversing.
 VisitStmt(If);
 
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp 
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index a331d5bc68286b..6c6aecb9994c6b 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -2050,12 +2050,7 @@ struct CounterCoverageMappingBuilder
 extendRegion(S->getCond());
 
 Counter ParentCount = getRegion().getCounter();
-auto [ThenCount, ElseCount] =
-(llvm::EnableSingleByteCoverage
- ? std::make_pair(getRegionCounter(S->getThen())

[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for CondOp (PR #113110)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/113110

>From 744c5b634de08f9214c82d6fcfde7179bc4edfb0 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 20 Oct 2024 14:46:07 +0900
Subject: [PATCH 1/4] [Coverage][Single] Enable Branch coverage for CondOp

---
 clang/lib/CodeGen/CGExpr.cpp  |  6 +--
 clang/lib/CodeGen/CGExprAgg.cpp   | 14 +--
 clang/lib/CodeGen/CGExprComplex.cpp   | 15 +---
 clang/lib/CodeGen/CGExprScalar.cpp| 37 +++
 clang/lib/CodeGen/CodeGenFunction.cpp |  3 +-
 clang/lib/CodeGen/CodeGenPGO.cpp  |  8 
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 16 ++--
 .../CoverageMapping/single-byte-counters.cpp  | 11 +++---
 8 files changed, 25 insertions(+), 85 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index cc85f05ad9f70c..67e3a1de17e679 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5137,8 +5137,7 @@ std::optional 
HandleConditionalOperatorLValueSimpleCase(
 
 if (!CGF.ContainsLabel(Dead)) {
   // If the true case is live, we need to track its region.
-  if (CondExprBool)
-CGF.incrementProfileCounter(E);
+  CGF.incrementProfileCounter(!CondExprBool, E, true);
   CGF.markStmtMaybeUsed(Dead);
   // If a throw expression we emit it and return an undefined lvalue
   // because it can't be used.
@@ -5177,7 +5176,7 @@ ConditionalInfo EmitConditionalBlocks(CodeGenFunction 
&CGF,
 
   // Any temporaries created here are conditional.
   CGF.EmitBlock(Info.lhsBlock);
-  CGF.incrementProfileCounter(E);
+  CGF.incrementProfileCounter(false, E);
   eval.begin(CGF);
   Info.LHS = BranchGenFunc(CGF, E->getTrueExpr());
   eval.end(CGF);
@@ -5188,6 +5187,7 @@ ConditionalInfo EmitConditionalBlocks(CodeGenFunction 
&CGF,
 
   // Any temporaries created here are conditional.
   CGF.EmitBlock(Info.rhsBlock);
+  CGF.incrementProfileCounter(true, E);
   eval.begin(CGF);
   Info.RHS = BranchGenFunc(CGF, E->getFalseExpr());
   eval.end(CGF);
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 2ad6587089f101..0c778ef185532f 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -36,10 +36,6 @@ using namespace CodeGen;
 //Aggregate Expression Emitter
 
//===--===//
 
-namespace llvm {
-extern cl::opt EnableSingleByteCoverage;
-} // namespace llvm
-
 namespace {
 class AggExprEmitter : public StmtVisitor {
   CodeGenFunction &CGF;
@@ -1293,10 +1289,7 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 
   eval.begin(CGF);
   CGF.EmitBlock(LHSBlock);
-  if (llvm::EnableSingleByteCoverage)
-CGF.incrementProfileCounter(E->getTrueExpr());
-  else
-CGF.incrementProfileCounter(E);
+  CGF.incrementProfileCounter(false, E);
   Visit(E->getTrueExpr());
   eval.end(CGF);
 
@@ -1311,8 +1304,7 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 
   eval.begin(CGF);
   CGF.EmitBlock(RHSBlock);
-  if (llvm::EnableSingleByteCoverage)
-CGF.incrementProfileCounter(E->getFalseExpr());
+  CGF.incrementProfileCounter(true, E);
   Visit(E->getFalseExpr());
   eval.end(CGF);
 
@@ -1321,8 +1313,6 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 E->getType());
 
   CGF.EmitBlock(ContBlock);
-  if (llvm::EnableSingleByteCoverage)
-CGF.incrementProfileCounter(E);
 }
 
 void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp 
b/clang/lib/CodeGen/CGExprComplex.cpp
index fef26e7b4ccdbd..bcece9431de764 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -28,10 +28,6 @@ using namespace CodeGen;
 //Complex Expression Emitter
 
//===--===//
 
-namespace llvm {
-extern cl::opt EnableSingleByteCoverage;
-} // namespace llvm
-
 typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
 
 /// Return the complex type that we are meant to emit.
@@ -1381,11 +1377,7 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 
   eval.begin(CGF);
   CGF.EmitBlock(LHSBlock);
-  if (llvm::EnableSingleByteCoverage)
-CGF.incrementProfileCounter(E->getTrueExpr());
-  else
-CGF.incrementProfileCounter(E);
-
+  CGF.incrementProfileCounter(false, E);
   ComplexPairTy LHS = Visit(E->getTrueExpr());
   LHSBlock = Builder.GetInsertBlock();
   CGF.EmitBranch(ContBlock);
@@ -1393,13 +1385,10 @@ VisitAbstractConditionalOperator(const 
AbstractConditionalOperator *E) {
 
   eval.begin(CGF);
   CGF.EmitBlock(RHSBlock);
-  if (llvm::EnableSingleByteCoverage)
-CGF.incrementProfileCounter(E->getFalseExpr());
+  CGF.incrementProfileCounter(true, E);
   Com

[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for `BinLAnd` and `BinLOr` (PR #113113)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/113113

>From 16e2bb8b73bcde1c2618bb358a905a9f463c1217 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 20 Oct 2024 16:24:26 +0900
Subject: [PATCH 1/3] [Coverage][Single] Enable Branch coverage for `BinLAnd`
 and `BinLOr`

---
 clang/lib/CodeGen/CGExprScalar.cpp   | 83 +++-
 clang/lib/CodeGen/CGStmt.cpp |  4 --
 clang/lib/CodeGen/CodeGenFunction.cpp| 43 ++--
 clang/lib/CodeGen/CoverageMappingGen.cpp |  6 --
 4 files changed, 104 insertions(+), 32 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 11d4ec8a267605..83962ba96aa484 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4918,6 +4918,9 @@ Value *ScalarExprEmitter::VisitBinAssign(const 
BinaryOperator *E) {
 }
 
 Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
+  auto HasLHSSkip = CGF.getIsCounterPair(E);
+  auto HasRHSSkip = CGF.getIsCounterPair(E->getRHS());
+
   // Perform vector logical and on comparisons with zero vectors.
   if (E->getType()->isVectorType()) {
 CGF.incrementProfileCounter(E);
@@ -4964,11 +4967,17 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
 CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
 llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end");
+llvm::BasicBlock *RHSSkip =
+(HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : 
FBlock);
 llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
-Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
+Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
 CGF.EmitBlock(RHSBlockCnt);
-CGF.incrementProfileCounter(E->getRHS());
+CGF.incrementProfileCounter(false, E->getRHS());
 CGF.EmitBranch(FBlock);
+if (HasRHSSkip.second) {
+  CGF.EmitBlock(RHSSkip);
+  CGF.incrementProfileCounter(true, E->getRHS());
+}
 CGF.EmitBlock(FBlock);
   }
 
@@ -4997,12 +5006,21 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
   llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
 
+  llvm::BasicBlock *LHSFalseBlock =
+  (HasLHSSkip.second ? CGF.createBasicBlock("land.lhsskip") : ContBlock);
+
   CodeGenFunction::ConditionalEvaluation eval(CGF);
 
   // Branch on the LHS first.  If it is false, go to the failure (cont) block.
-  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
+  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, LHSFalseBlock,
CGF.getProfileCount(E->getRHS()));
 
+  if (HasLHSSkip.second) {
+CGF.EmitBlock(LHSFalseBlock);
+CGF.incrementProfileCounter(true, E);
+CGF.EmitBranch(ContBlock);
+  }
+
   // Any edges into the ContBlock are now from an (indeterminate number of)
   // edges from this first condition.  All of these values will be false.  
Start
   // setting up the PHI node in the Cont Block for this.
@@ -5014,7 +5032,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
 
   eval.begin(CGF);
   CGF.EmitBlock(RHSBlock);
-  CGF.incrementProfileCounter(E);
+  CGF.incrementProfileCounter(false, E);
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
   eval.end(CGF);
 
@@ -5024,15 +5042,24 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   // If we're generating for profiling or coverage, generate a branch on the
   // RHS to a block that increments the RHS true counter needed to track branch
   // condition coverage.
+  llvm::BasicBlock *ContIncoming = RHSBlock;
   if (InstrumentRegions &&
   CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
 CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
 llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
-Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
+llvm::BasicBlock *RHSBlockSkip =
+(HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : ContBlock);
+Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
 CGF.EmitBlock(RHSBlockCnt);
-CGF.incrementProfileCounter(E->getRHS());
+CGF.incrementProfileCounter(false, E->getRHS());
 CGF.EmitBranch(ContBlock);
 PN->addIncoming(RHSCond, RHSBlockCnt);
+if (HasRHSSkip.second) {
+  CGF.EmitBlock(RHSBlockSkip);
+  CGF.incrementProfileCounter(true, E->getRHS());
+  CGF.EmitBranch(ContBlock);
+  ContIncoming = RHSBlockSkip;
+}
   }
 
   // Emit an unconditional branch from this block to ContBlock.
@@ -5042,7 +5069,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
 CGF.EmitBlock(ContBlock);
   }
   // Insert an entry into the phi node for the edge with the value of RHSCond.

[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for `BinLAnd` and `BinLOr` (PR #113113)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/113113

>From 16e2bb8b73bcde1c2618bb358a905a9f463c1217 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sun, 20 Oct 2024 16:24:26 +0900
Subject: [PATCH 1/3] [Coverage][Single] Enable Branch coverage for `BinLAnd`
 and `BinLOr`

---
 clang/lib/CodeGen/CGExprScalar.cpp   | 83 +++-
 clang/lib/CodeGen/CGStmt.cpp |  4 --
 clang/lib/CodeGen/CodeGenFunction.cpp| 43 ++--
 clang/lib/CodeGen/CoverageMappingGen.cpp |  6 --
 4 files changed, 104 insertions(+), 32 deletions(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 11d4ec8a267605..83962ba96aa484 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4918,6 +4918,9 @@ Value *ScalarExprEmitter::VisitBinAssign(const 
BinaryOperator *E) {
 }
 
 Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
+  auto HasLHSSkip = CGF.getIsCounterPair(E);
+  auto HasRHSSkip = CGF.getIsCounterPair(E->getRHS());
+
   // Perform vector logical and on comparisons with zero vectors.
   if (E->getType()->isVectorType()) {
 CGF.incrementProfileCounter(E);
@@ -4964,11 +4967,17 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
 CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
 llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end");
+llvm::BasicBlock *RHSSkip =
+(HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : 
FBlock);
 llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
-Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
+Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip);
 CGF.EmitBlock(RHSBlockCnt);
-CGF.incrementProfileCounter(E->getRHS());
+CGF.incrementProfileCounter(false, E->getRHS());
 CGF.EmitBranch(FBlock);
+if (HasRHSSkip.second) {
+  CGF.EmitBlock(RHSSkip);
+  CGF.incrementProfileCounter(true, E->getRHS());
+}
 CGF.EmitBlock(FBlock);
   }
 
@@ -4997,12 +5006,21 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end");
   llvm::BasicBlock *RHSBlock  = CGF.createBasicBlock("land.rhs");
 
+  llvm::BasicBlock *LHSFalseBlock =
+  (HasLHSSkip.second ? CGF.createBasicBlock("land.lhsskip") : ContBlock);
+
   CodeGenFunction::ConditionalEvaluation eval(CGF);
 
   // Branch on the LHS first.  If it is false, go to the failure (cont) block.
-  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock,
+  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, LHSFalseBlock,
CGF.getProfileCount(E->getRHS()));
 
+  if (HasLHSSkip.second) {
+CGF.EmitBlock(LHSFalseBlock);
+CGF.incrementProfileCounter(true, E);
+CGF.EmitBranch(ContBlock);
+  }
+
   // Any edges into the ContBlock are now from an (indeterminate number of)
   // edges from this first condition.  All of these values will be false.  
Start
   // setting up the PHI node in the Cont Block for this.
@@ -5014,7 +5032,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
 
   eval.begin(CGF);
   CGF.EmitBlock(RHSBlock);
-  CGF.incrementProfileCounter(E);
+  CGF.incrementProfileCounter(false, E);
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
   eval.end(CGF);
 
@@ -5024,15 +5042,24 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
   // If we're generating for profiling or coverage, generate a branch on the
   // RHS to a block that increments the RHS true counter needed to track branch
   // condition coverage.
+  llvm::BasicBlock *ContIncoming = RHSBlock;
   if (InstrumentRegions &&
   CodeGenFunction::isInstrumentedCondition(E->getRHS())) {
 CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond);
 llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt");
-Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
+llvm::BasicBlock *RHSBlockSkip =
+(HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : ContBlock);
+Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip);
 CGF.EmitBlock(RHSBlockCnt);
-CGF.incrementProfileCounter(E->getRHS());
+CGF.incrementProfileCounter(false, E->getRHS());
 CGF.EmitBranch(ContBlock);
 PN->addIncoming(RHSCond, RHSBlockCnt);
+if (HasRHSSkip.second) {
+  CGF.EmitBlock(RHSBlockSkip);
+  CGF.incrementProfileCounter(true, E->getRHS());
+  CGF.EmitBranch(ContBlock);
+  ContIncoming = RHSBlockSkip;
+}
   }
 
   // Emit an unconditional branch from this block to ContBlock.
@@ -5042,7 +5069,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const 
BinaryOperator *E) {
 CGF.EmitBlock(ContBlock);
   }
   // Insert an entry into the phi node for the edge with the value of RHSCond.

[llvm-branch-commits] [clang] [llvm] [Coverage][Single] Enable Branch coverage for loop statements (PR #113109)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/113109

>From 5d19c77551c6fc585d1b15c4c2a71c3c3f99ef8a Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Fri, 18 Oct 2024 09:33:51 +0900
Subject: [PATCH 1/3] [Coverage][Single] Enable Branch coverage for loop
 statements

---
 clang/lib/CodeGen/CGStmt.cpp  |  82 ---
 clang/lib/CodeGen/CodeGenFunction.cpp |  11 +-
 clang/lib/CodeGen/CodeGenPGO.cpp  |  79 +--
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 130 +-
 .../CoverageMapping/single-byte-counters.cpp  |  53 +++
 5 files changed, 97 insertions(+), 258 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index dbc1ce9bf993cd..7d778ce58a1487 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1039,15 +1039,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
  SourceLocToDebugLoc(R.getEnd()),
  checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S)));
 
-  // When single byte coverage mode is enabled, add a counter to loop 
condition.
-  if (llvm::EnableSingleByteCoverage)
-incrementProfileCounter(S.getCond());
-
   // As long as the condition is true, go to the loop body.
   llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
   if (EmitBoolCondBranch) {
 llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
-if (ConditionScope.requiresCleanups())
+if (getIsCounterPair(&S).second || ConditionScope.requiresCleanups())
   ExitBlock = createBasicBlock("while.exit");
 llvm::MDNode *Weights =
 createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()));
@@ -1058,6 +1054,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
 
 if (ExitBlock != LoopExit.getBlock()) {
   EmitBlock(ExitBlock);
+  incrementProfileCounter(true, &S);
   EmitBranchThroughCleanup(LoopExit);
 }
   } else if (const Attr *A = Stmt::getLikelihoodAttr(S.getBody())) {
@@ -1075,11 +1072,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
   {
 RunCleanupsScope BodyScope(*this);
 EmitBlock(LoopBody);
-// When single byte coverage mode is enabled, add a counter to the body.
-if (llvm::EnableSingleByteCoverage)
-  incrementProfileCounter(S.getBody());
-else
-  incrementProfileCounter(&S);
+incrementProfileCounter(false, &S);
 EmitStmt(S.getBody());
   }
 
@@ -1099,13 +1092,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
 
   // The LoopHeader typically is just a branch if we skipped emitting
   // a branch, try to erase it.
-  if (!EmitBoolCondBranch)
+  if (!EmitBoolCondBranch) {
 SimplifyForwardingBlocks(LoopHeader.getBlock());
-
-  // When single byte coverage mode is enabled, add a counter to continuation
-  // block.
-  if (llvm::EnableSingleByteCoverage)
-incrementProfileCounter(&S);
+PGO.markStmtAsUsed(true, &S);
+  }
 
   if (CGM.shouldEmitConvergenceTokens())
 ConvergenceTokenStack.pop_back();
@@ -1124,10 +1114,7 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
   // Emit the body of the loop.
   llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
 
-  if (llvm::EnableSingleByteCoverage)
-EmitBlockWithFallThrough(LoopBody, S.getBody());
-  else
-EmitBlockWithFallThrough(LoopBody, &S);
+  EmitBlockWithFallThrough(LoopBody, &S);
 
   if (CGM.shouldEmitConvergenceTokens())
 ConvergenceTokenStack.push_back(
@@ -1139,9 +1126,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
   }
 
   EmitBlock(LoopCond.getBlock());
-  // When single byte coverage mode is enabled, add a counter to loop 
condition.
-  if (llvm::EnableSingleByteCoverage)
-incrementProfileCounter(S.getCond());
 
   // C99 6.8.5.2: "The evaluation of the controlling expression takes place
   // after each execution of the loop body."
@@ -1164,16 +1148,25 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
  SourceLocToDebugLoc(R.getEnd()),
  checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S)));
 
+  auto *LoopFalse =
+  (getIsCounterPair(&S).second ? createBasicBlock("do.loopfalse")
+   : LoopExit.getBlock());
+
   // As long as the condition is true, iterate the loop.
   if (EmitBoolCondBranch) {
 uint64_t BackedgeCount = getProfileCount(S.getBody()) - ParentCount;
 Builder.CreateCondBr(
-BoolCondVal, LoopBody, LoopExit.getBlock(),
+BoolCondVal, LoopBody, LoopFalse,
 createProfileWeightsForLoop(S.getCond(), BackedgeCount));
   }
 
   LoopStack.pop();
 
+  if (LoopFalse != LoopExit.getBlock()) {
+EmitBlock(LoopFalse);
+incrementProfileCounter(true, &S, true);
+  }
+
   // Emit the exit block.
   EmitBlock(LoopExit.getBlock());
 
@@ -1182,11 +1175,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
   if (!EmitBoolCondBranch)
 SimplifyForwardingBlocks(LoopCond.getBlock());

[llvm-branch-commits] [llvm] [Coverage] Move SingleByteCoverage out of CountedRegion (PR #110966)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni edited 
https://github.com/llvm/llvm-project/pull/110966
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] [llvm] [Coverage] Make additional counters available for BranchRegion. NFC. (PR #112730)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/112730

>From 5e460594c8a2550c38c759b2e6f1c5dc4152f820 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Thu, 17 Oct 2024 22:15:12 +0900
Subject: [PATCH 1/5] [Coverage] Make additional counters available for
 BranchRegion. NFC.

`getBranchCounterPair()` allocates an additional Counter to SkipPath
in `SingleByteCoverage`.

`IsCounterEqual()` calculates the comparison with rewinding counter
replacements.

`NumRegionCounters` is updated to take additional counters in account.

`incrementProfileCounter()` has a few additiona arguments.

- `UseSkipPath=true`, to specify setting counters for SkipPath. It
  assumes `UseSkipPath=false` is used together.

- `UseBoth` may be specified for marking another path. It introduces
  the same effect as issueing `markStmtAsUsed(!SkipPath, S)`.

`llvm-cov` discovers counters in `FalseCount` to allocate
`MaxCounterID` for empty profile data.
---
 clang/lib/CodeGen/CodeGenFunction.h   |  8 -
 clang/lib/CodeGen/CodeGenPGO.cpp  | 31 +--
 clang/lib/CodeGen/CodeGenPGO.h|  1 +
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 31 ++-
 .../ProfileData/Coverage/CoverageMapping.cpp  |  4 +++
 5 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 89ac3b342d0a7c..cb1192bf6e11fe 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1629,11 +1629,17 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Increment the profiler's counter for the given statement by \p StepV.
   /// If \p StepV is null, the default increment is 1.
   void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
+incrementProfileCounter(false, S, false, StepV);
+  }
+
+  void incrementProfileCounter(bool UseSkipPath, const Stmt *S,
+   bool UseBoth = false,
+   llvm::Value *StepV = nullptr) {
 if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
 !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
 !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) {
   auto AL = ApplyDebugLocation::CreateArtificial(*this);
-  PGO.emitCounterSetOrIncrement(Builder, S, StepV);
+  PGO.emitCounterSetOrIncrement(Builder, S, UseSkipPath, UseBoth, StepV);
 }
 PGO.setCurrentStmt(S);
   }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 069469e3de856b..aefd53e12088b4 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -1138,6 +1138,19 @@ void CodeGenPGO::emitCounterRegionMapping(const Decl *D) 
{
   if (CoverageMapping.empty())
 return;
 
+  // Scan max(FalseCnt) and update NumRegionCounters.
+  unsigned MaxNumCounters = NumRegionCounters;
+  for (const auto [_, V] : *RegionCounterMap) {
+auto HasCounters = V.getIsCounterPair();
+assert((!HasCounters.first ||
+MaxNumCounters > (V.first & CounterPair::Mask)) &&
+   "TrueCnt should not be reassigned");
+if (HasCounters.second)
+  MaxNumCounters =
+  std::max(MaxNumCounters, (V.second & CounterPair::Mask) + 1);
+  }
+  NumRegionCounters = MaxNumCounters;
+
   CGM.getCoverageMapping()->addFunctionMappingRecord(
   FuncNameVar, FuncName, FunctionHash, CoverageMapping);
 }
@@ -1193,11 +1206,25 @@ std::pair 
CodeGenPGO::getIsCounterPair(const Stmt *S) const {
 }
 
 void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
+   bool UseSkipPath, bool UseBoth,
llvm::Value *StepV) {
-  if (!RegionCounterMap || !Builder.GetInsertBlock())
+  if (!RegionCounterMap)
 return;
 
-  unsigned Counter = (*RegionCounterMap)[S].first;
+  unsigned Counter;
+  auto &TheMap = (*RegionCounterMap)[S];
+  auto IsCounter = TheMap.getIsCounterPair();
+  if (!UseSkipPath) {
+assert(IsCounter.first);
+Counter = (TheMap.first & CounterPair::Mask);
+  } else {
+if (!IsCounter.second)
+  return;
+Counter = (TheMap.second & CounterPair::Mask);
+  }
+
+  if (!Builder.GetInsertBlock())
+return;
 
   // Make sure that pointer to global is passed in with zero addrspace
   // This is relevant during GPU profiling
diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h
index 83f35785e5327d..8b769dd88d7f1e 100644
--- a/clang/lib/CodeGen/CodeGenPGO.h
+++ b/clang/lib/CodeGen/CodeGenPGO.h
@@ -112,6 +112,7 @@ class CodeGenPGO {
 public:
   std::pair getIsCounterPair(const Stmt *S) const;
   void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
+ bool UseFalsePath, bool UseBoth,
  llvm::Value *StepV);
   void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S,

[llvm-branch-commits] [compiler-rt] [llvm] [Coverage][Single] Round Counters to boolean after evaluation (PR #110972)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/110972

>From 178b57cbbcb2b21b7d13f90ffd75903417913438 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Wed, 2 Oct 2024 23:11:36 +0900
Subject: [PATCH 1/5] [Coverage] Move SingleByteCoverage out of CountedRegion

`SingleByteCoverage` is not per-region attribute at least.
At the moment, this change moves it into `FunctionRecord`.
---
 .../ProfileData/Coverage/CoverageMapping.h| 27 +++---
 .../ProfileData/Coverage/CoverageMapping.cpp  | 36 ---
 2 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h 
b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index fa07b3a9e8b14f..77c447efe1a7c9 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -359,19 +359,15 @@ struct CountedRegion : public CounterMappingRegion {
   uint64_t ExecutionCount;
   uint64_t FalseExecutionCount;
   bool Folded;
-  bool HasSingleByteCoverage;
 
-  CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
-bool HasSingleByteCoverage)
+  CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
   : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
-FalseExecutionCount(0), Folded(false),
-HasSingleByteCoverage(HasSingleByteCoverage) {}
+FalseExecutionCount(0), Folded(false) {}
 
   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
-uint64_t FalseExecutionCount, bool HasSingleByteCoverage)
+uint64_t FalseExecutionCount)
   : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
-FalseExecutionCount(FalseExecutionCount), Folded(false),
-HasSingleByteCoverage(HasSingleByteCoverage) {}
+FalseExecutionCount(FalseExecutionCount), Folded(false) {}
 };
 
 /// MCDC Record grouping all information together.
@@ -702,9 +698,12 @@ struct FunctionRecord {
   std::vector MCDCRecords;
   /// The number of times this function was executed.
   uint64_t ExecutionCount = 0;
+  bool SingleByteCoverage;
 
-  FunctionRecord(StringRef Name, ArrayRef Filenames)
-  : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
+  FunctionRecord(StringRef Name, ArrayRef Filenames,
+ bool SingleByteCoverage)
+  : Name(Name), Filenames(Filenames.begin(), Filenames.end()),
+SingleByteCoverage(SingleByteCoverage) {}
 
   FunctionRecord(FunctionRecord &&FR) = default;
   FunctionRecord &operator=(FunctionRecord &&) = default;
@@ -714,11 +713,10 @@ struct FunctionRecord {
   }
 
   void pushRegion(CounterMappingRegion Region, uint64_t Count,
-  uint64_t FalseCount, bool HasSingleByteCoverage) {
+  uint64_t FalseCount) {
 if (Region.Kind == CounterMappingRegion::BranchRegion ||
 Region.Kind == CounterMappingRegion::MCDCBranchRegion) {
-  CountedBranchRegions.emplace_back(Region, Count, FalseCount,
-HasSingleByteCoverage);
+  CountedBranchRegions.emplace_back(Region, Count, FalseCount);
   // If both counters are hard-coded to zero, then this region represents a
   // constant-folded branch.
   if (Region.Count.isZero() && Region.FalseCount.isZero())
@@ -727,8 +725,7 @@ struct FunctionRecord {
 }
 if (CountedRegions.empty())
   ExecutionCount = Count;
-CountedRegions.emplace_back(Region, Count, FalseCount,
-HasSingleByteCoverage);
+CountedRegions.emplace_back(Region, Count, FalseCount);
   }
 };
 
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp 
b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 18643c6b44485e..a02136d5b0386d 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -808,6 +808,7 @@ Error CoverageMapping::loadFunctionRecord(
   else
 OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
 
+  bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
   CounterMappingContext Ctx(Record.Expressions);
 
   std::vector Counts;
@@ -855,7 +856,7 @@ Error CoverageMapping::loadFunctionRecord(
 return Error::success();
 
   MCDCDecisionRecorder MCDCDecisions;
-  FunctionRecord Function(OrigFuncName, Record.Filenames);
+  FunctionRecord Function(OrigFuncName, Record.Filenames, SingleByteCoverage);
   for (const auto &Region : Record.MappingRegions) {
 // MCDCDecisionRegion should be handled first since it overlaps with
 // others inside.
@@ -873,8 +874,7 @@ Error CoverageMapping::loadFunctionRecord(
   consumeError(std::move(E));
   return Error::success();
 }
-Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount,
-ProfileReader.hasSingleByteCoverage());
+Function.pushRegion(Regio

[llvm-branch-commits] [compiler-rt] [llvm] [Coverage][Single] Round Counters to boolean after evaluation (PR #110972)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/110972

>From 178b57cbbcb2b21b7d13f90ffd75903417913438 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Wed, 2 Oct 2024 23:11:36 +0900
Subject: [PATCH 1/5] [Coverage] Move SingleByteCoverage out of CountedRegion

`SingleByteCoverage` is not per-region attribute at least.
At the moment, this change moves it into `FunctionRecord`.
---
 .../ProfileData/Coverage/CoverageMapping.h| 27 +++---
 .../ProfileData/Coverage/CoverageMapping.cpp  | 36 ---
 2 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h 
b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index fa07b3a9e8b14f..77c447efe1a7c9 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -359,19 +359,15 @@ struct CountedRegion : public CounterMappingRegion {
   uint64_t ExecutionCount;
   uint64_t FalseExecutionCount;
   bool Folded;
-  bool HasSingleByteCoverage;
 
-  CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
-bool HasSingleByteCoverage)
+  CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
   : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
-FalseExecutionCount(0), Folded(false),
-HasSingleByteCoverage(HasSingleByteCoverage) {}
+FalseExecutionCount(0), Folded(false) {}
 
   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
-uint64_t FalseExecutionCount, bool HasSingleByteCoverage)
+uint64_t FalseExecutionCount)
   : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
-FalseExecutionCount(FalseExecutionCount), Folded(false),
-HasSingleByteCoverage(HasSingleByteCoverage) {}
+FalseExecutionCount(FalseExecutionCount), Folded(false) {}
 };
 
 /// MCDC Record grouping all information together.
@@ -702,9 +698,12 @@ struct FunctionRecord {
   std::vector MCDCRecords;
   /// The number of times this function was executed.
   uint64_t ExecutionCount = 0;
+  bool SingleByteCoverage;
 
-  FunctionRecord(StringRef Name, ArrayRef Filenames)
-  : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
+  FunctionRecord(StringRef Name, ArrayRef Filenames,
+ bool SingleByteCoverage)
+  : Name(Name), Filenames(Filenames.begin(), Filenames.end()),
+SingleByteCoverage(SingleByteCoverage) {}
 
   FunctionRecord(FunctionRecord &&FR) = default;
   FunctionRecord &operator=(FunctionRecord &&) = default;
@@ -714,11 +713,10 @@ struct FunctionRecord {
   }
 
   void pushRegion(CounterMappingRegion Region, uint64_t Count,
-  uint64_t FalseCount, bool HasSingleByteCoverage) {
+  uint64_t FalseCount) {
 if (Region.Kind == CounterMappingRegion::BranchRegion ||
 Region.Kind == CounterMappingRegion::MCDCBranchRegion) {
-  CountedBranchRegions.emplace_back(Region, Count, FalseCount,
-HasSingleByteCoverage);
+  CountedBranchRegions.emplace_back(Region, Count, FalseCount);
   // If both counters are hard-coded to zero, then this region represents a
   // constant-folded branch.
   if (Region.Count.isZero() && Region.FalseCount.isZero())
@@ -727,8 +725,7 @@ struct FunctionRecord {
 }
 if (CountedRegions.empty())
   ExecutionCount = Count;
-CountedRegions.emplace_back(Region, Count, FalseCount,
-HasSingleByteCoverage);
+CountedRegions.emplace_back(Region, Count, FalseCount);
   }
 };
 
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp 
b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 18643c6b44485e..a02136d5b0386d 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -808,6 +808,7 @@ Error CoverageMapping::loadFunctionRecord(
   else
 OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
 
+  bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
   CounterMappingContext Ctx(Record.Expressions);
 
   std::vector Counts;
@@ -855,7 +856,7 @@ Error CoverageMapping::loadFunctionRecord(
 return Error::success();
 
   MCDCDecisionRecorder MCDCDecisions;
-  FunctionRecord Function(OrigFuncName, Record.Filenames);
+  FunctionRecord Function(OrigFuncName, Record.Filenames, SingleByteCoverage);
   for (const auto &Region : Record.MappingRegions) {
 // MCDCDecisionRegion should be handled first since it overlaps with
 // others inside.
@@ -873,8 +874,7 @@ Error CoverageMapping::loadFunctionRecord(
   consumeError(std::move(E));
   return Error::success();
 }
-Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount,
-ProfileReader.hasSingleByteCoverage());
+Function.pushRegion(Regio

[llvm-branch-commits] [clang] [llvm] [Coverage] Make additional counters available for BranchRegion. NFC. (PR #112730)

2024-12-21 Thread NAKAMURA Takumi via llvm-branch-commits

https://github.com/chapuni updated 
https://github.com/llvm/llvm-project/pull/112730

>From 5e460594c8a2550c38c759b2e6f1c5dc4152f820 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Thu, 17 Oct 2024 22:15:12 +0900
Subject: [PATCH 1/5] [Coverage] Make additional counters available for
 BranchRegion. NFC.

`getBranchCounterPair()` allocates an additional Counter to SkipPath
in `SingleByteCoverage`.

`IsCounterEqual()` calculates the comparison with rewinding counter
replacements.

`NumRegionCounters` is updated to take additional counters in account.

`incrementProfileCounter()` has a few additiona arguments.

- `UseSkipPath=true`, to specify setting counters for SkipPath. It
  assumes `UseSkipPath=false` is used together.

- `UseBoth` may be specified for marking another path. It introduces
  the same effect as issueing `markStmtAsUsed(!SkipPath, S)`.

`llvm-cov` discovers counters in `FalseCount` to allocate
`MaxCounterID` for empty profile data.
---
 clang/lib/CodeGen/CodeGenFunction.h   |  8 -
 clang/lib/CodeGen/CodeGenPGO.cpp  | 31 +--
 clang/lib/CodeGen/CodeGenPGO.h|  1 +
 clang/lib/CodeGen/CoverageMappingGen.cpp  | 31 ++-
 .../ProfileData/Coverage/CoverageMapping.cpp  |  4 +++
 5 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 89ac3b342d0a7c..cb1192bf6e11fe 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1629,11 +1629,17 @@ class CodeGenFunction : public CodeGenTypeCache {
   /// Increment the profiler's counter for the given statement by \p StepV.
   /// If \p StepV is null, the default increment is 1.
   void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
+incrementProfileCounter(false, S, false, StepV);
+  }
+
+  void incrementProfileCounter(bool UseSkipPath, const Stmt *S,
+   bool UseBoth = false,
+   llvm::Value *StepV = nullptr) {
 if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
 !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
 !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) {
   auto AL = ApplyDebugLocation::CreateArtificial(*this);
-  PGO.emitCounterSetOrIncrement(Builder, S, StepV);
+  PGO.emitCounterSetOrIncrement(Builder, S, UseSkipPath, UseBoth, StepV);
 }
 PGO.setCurrentStmt(S);
   }
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 069469e3de856b..aefd53e12088b4 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -1138,6 +1138,19 @@ void CodeGenPGO::emitCounterRegionMapping(const Decl *D) 
{
   if (CoverageMapping.empty())
 return;
 
+  // Scan max(FalseCnt) and update NumRegionCounters.
+  unsigned MaxNumCounters = NumRegionCounters;
+  for (const auto [_, V] : *RegionCounterMap) {
+auto HasCounters = V.getIsCounterPair();
+assert((!HasCounters.first ||
+MaxNumCounters > (V.first & CounterPair::Mask)) &&
+   "TrueCnt should not be reassigned");
+if (HasCounters.second)
+  MaxNumCounters =
+  std::max(MaxNumCounters, (V.second & CounterPair::Mask) + 1);
+  }
+  NumRegionCounters = MaxNumCounters;
+
   CGM.getCoverageMapping()->addFunctionMappingRecord(
   FuncNameVar, FuncName, FunctionHash, CoverageMapping);
 }
@@ -1193,11 +1206,25 @@ std::pair 
CodeGenPGO::getIsCounterPair(const Stmt *S) const {
 }
 
 void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
+   bool UseSkipPath, bool UseBoth,
llvm::Value *StepV) {
-  if (!RegionCounterMap || !Builder.GetInsertBlock())
+  if (!RegionCounterMap)
 return;
 
-  unsigned Counter = (*RegionCounterMap)[S].first;
+  unsigned Counter;
+  auto &TheMap = (*RegionCounterMap)[S];
+  auto IsCounter = TheMap.getIsCounterPair();
+  if (!UseSkipPath) {
+assert(IsCounter.first);
+Counter = (TheMap.first & CounterPair::Mask);
+  } else {
+if (!IsCounter.second)
+  return;
+Counter = (TheMap.second & CounterPair::Mask);
+  }
+
+  if (!Builder.GetInsertBlock())
+return;
 
   // Make sure that pointer to global is passed in with zero addrspace
   // This is relevant during GPU profiling
diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h
index 83f35785e5327d..8b769dd88d7f1e 100644
--- a/clang/lib/CodeGen/CodeGenPGO.h
+++ b/clang/lib/CodeGen/CodeGenPGO.h
@@ -112,6 +112,7 @@ class CodeGenPGO {
 public:
   std::pair getIsCounterPair(const Stmt *S) const;
   void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
+ bool UseFalsePath, bool UseBoth,
  llvm::Value *StepV);
   void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S,

[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value 
value) {
   return OpBuilder::InsertPoint(insertBlock, insertPt);
 }
 
+/// Helper function that computes an insertion point where the given values are
+/// defined and can be used without a dominance violation.
+static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) {
+  assert(!vals.empty() && "expected at least one value");
+  OpBuilder::InsertPoint pt = computeInsertPoint(vals.front());
+  for (Value v : vals.drop_front())
+pt = chooseLaterInsertPoint(pt, computeInsertPoint(v));
+  return pt;
+}
+
 
//===--===//
 // ConversionValueMapping
 
//===--===//
 
+/// A vector of SSA values, optimized for the most common case of a single
+/// value.
+using ValueVector = SmallVector;
+
 namespace {
+
+/// Helper class to make it possible to use `ValueVector` as a key in DenseMap.
+struct ValueVectorMapInfo {
+  static ValueVector getEmptyKey() { return ValueVector{}; }
+  static ValueVector getTombstoneKey() { return ValueVector{}; }
+  static ::llvm::hash_code getHashValue(ValueVector val) {
+return ::llvm::hash_combine_range(val.begin(), val.end());
+  }
+  static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; }
+};
+
 /// This class wraps a IRMapping to provide recursive lookup
 /// functionality, i.e. we will traverse if the mapped value also has a 
mapping.
 struct ConversionValueMapping {
   /// Return "true" if an SSA value is mapped to the given value. May return
   /// false positives.
   bool isMappedTo(Value value) const { return mappedTo.contains(value); }
 
-  /// Lookup the most recently mapped value with the desired type in the
+  /// Lookup the most recently mapped values with the desired types in the
   /// mapping.
   ///
   /// Special cases:
-  /// - If the desired type is "null", simply return the most recently mapped
-  ///   value.
-  /// - If there is no mapping to the desired type, also return the most
-  ///   recently mapped value.
-  /// - If there is no mapping for the given value at all, return the given
-  ///   value.
-  Value lookupOrDefault(Value from, Type desiredType = nullptr) const;
-
-  /// Lookup a mapped value within the map, or return null if a mapping does 
not
-  /// exist. If a mapping exists, this follows the same behavior of
-  /// `lookupOrDefault`.
-  Value lookupOrNull(Value from, Type desiredType = nullptr) const;
+  /// - If the desired type range is empty, simply return the most recently
+  ///   mapped values.
+  /// - If there is no mapping to the desired types, also return the most
+  ///   recently mapped values.
+  /// - If there is no mapping for the given values at all, return the given
+  ///   values.
+  ValueVector lookupOrDefault(ValueVector from,
+  TypeRange desiredTypes = {}) const;
+
+  /// Lookup the given values within the map, or return an empty vector if the
+  /// values are not mapped. If they are mapped, this follows the same behavior
+  /// as `lookupOrDefault`.
+  ValueVector lookupOrNull(const ValueVector &from,
+   TypeRange desiredTypes = {}) const;
 
   /// Map a value to the one provided.
-  void map(Value oldVal, Value newVal) {
+  void map(const ValueVector &oldVal, const ValueVector &newVal) {
 LLVM_DEBUG({
-  for (Value it = newVal; it; it = mapping.lookupOrNull(it))
-assert(it != oldVal && "inserting cyclic mapping");
+  ValueVector next = newVal;
+  while (true) {
+assert(next != oldVal && "inserting cyclic mapping");
+auto it = mapping.find(next);
+if (it == mapping.end())
+  break;
+next = it->second;
+  }
 });
-mapping.map(oldVal, newVal);
-mappedTo.insert(newVal);
+mapping[oldVal] = newVal;
+for (Value v : newVal)
+  mappedTo.insert(v);
   }
 
-  /// Drop the last mapping for the given value.
-  void erase(Value value) { mapping.erase(value); }
+  /// Drop the last mapping for the given values.
+  void erase(ValueVector value) { mapping.erase(value); }
 
 private:
   /// Current value mappings.
-  IRMapping mapping;
+  DenseMap mapping;
 
   /// All SSA values that are mapped to. May contain false positives.
   DenseSet mappedTo;
 };
 } // namespace
 
-Value ConversionValueMapping::lookupOrDefault(Value from,
-  Type desiredType) const {
-  // Try to find the deepest value that has the desired type. If there is no
-  // such value, simply return the deepest value.
-  Value desiredValue;
+ValueVector
+ConversionValueMapping::lookupOrDefault(ValueVector from,
+TypeRange desiredTypes) const {
+  // Try to find the deepest values that have the desired types. If there is no
+  // such mapping, simply return the deepest values.
+  ValueVe

[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value 
value) {
   return OpBuilder::InsertPoint(insertBlock, insertPt);
 }
 
+/// Helper function that computes an insertion point where the given values are
+/// defined and can be used without a dominance violation.
+static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) {
+  assert(!vals.empty() && "expected at least one value");
+  OpBuilder::InsertPoint pt = computeInsertPoint(vals.front());
+  for (Value v : vals.drop_front())
+pt = chooseLaterInsertPoint(pt, computeInsertPoint(v));
+  return pt;
+}
+
 
//===--===//
 // ConversionValueMapping
 
//===--===//
 
+/// A vector of SSA values, optimized for the most common case of a single
+/// value.
+using ValueVector = SmallVector;
+
 namespace {
+
+/// Helper class to make it possible to use `ValueVector` as a key in DenseMap.
+struct ValueVectorMapInfo {
+  static ValueVector getEmptyKey() { return ValueVector{}; }
+  static ValueVector getTombstoneKey() { return ValueVector{}; }
+  static ::llvm::hash_code getHashValue(ValueVector val) {
+return ::llvm::hash_combine_range(val.begin(), val.end());
+  }
+  static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; }
+};
+
 /// This class wraps a IRMapping to provide recursive lookup
 /// functionality, i.e. we will traverse if the mapped value also has a 
mapping.
 struct ConversionValueMapping {
   /// Return "true" if an SSA value is mapped to the given value. May return
   /// false positives.
   bool isMappedTo(Value value) const { return mappedTo.contains(value); }
 
-  /// Lookup the most recently mapped value with the desired type in the
+  /// Lookup the most recently mapped values with the desired types in the
   /// mapping.
   ///
   /// Special cases:
-  /// - If the desired type is "null", simply return the most recently mapped
-  ///   value.
-  /// - If there is no mapping to the desired type, also return the most
-  ///   recently mapped value.
-  /// - If there is no mapping for the given value at all, return the given
-  ///   value.
-  Value lookupOrDefault(Value from, Type desiredType = nullptr) const;
-
-  /// Lookup a mapped value within the map, or return null if a mapping does 
not
-  /// exist. If a mapping exists, this follows the same behavior of
-  /// `lookupOrDefault`.
-  Value lookupOrNull(Value from, Type desiredType = nullptr) const;
+  /// - If the desired type range is empty, simply return the most recently
+  ///   mapped values.
+  /// - If there is no mapping to the desired types, also return the most
+  ///   recently mapped values.
+  /// - If there is no mapping for the given values at all, return the given
+  ///   values.
+  ValueVector lookupOrDefault(ValueVector from,
+  TypeRange desiredTypes = {}) const;
+
+  /// Lookup the given values within the map, or return an empty vector if the
+  /// values are not mapped. If they are mapped, this follows the same behavior
+  /// as `lookupOrDefault`.
+  ValueVector lookupOrNull(const ValueVector &from,
+   TypeRange desiredTypes = {}) const;
 
   /// Map a value to the one provided.
-  void map(Value oldVal, Value newVal) {
+  void map(const ValueVector &oldVal, const ValueVector &newVal) {

zero9178 wrote:

There's a few callers that call these with r-values where a move construction 
would avoid copying entirely.
Could we change these to be universal references and then use `std::forward` 
for the `operator[]` + assignment at line 184?

I prototyped this a bit roughly here if you'd like to cherry-pick in the 
changes: 
https://github.com/llvm/llvm-project/commit/5e857ac6348e7455f1c72fd49eb887fc1406949c

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1192,51 +1256,28 @@ LogicalResult 
ConversionPatternRewriterImpl::remapValues(
   });
   return failure();
 }
-
 // If a type is converted to 0 types, there is nothing to do.
 if (legalTypes.empty()) {
   remapped.push_back({});
   continue;
 }
 
-if (legalTypes.size() != 1) {
-  // TODO: This is a 1:N conversion. The conversion value mapping does not
-  // store such materializations yet. If the types of the most recently
-  // mapped values do not match, build a target materialization.
-  ValueRange unpackedRange(unpacked);
-  if (TypeRange(unpackedRange) == legalTypes) {
-remapped.push_back(std::move(unpacked));
-continue;
-  }
-
-  // Insert a target materialization if the current pattern expects
-  // different legalized types.
-  ValueRange targetMat = buildUnresolvedMaterialization(
-  MaterializationKind::Target, computeInsertPoint(repl), operandLoc,
-  /*valueToMap=*/Value(), /*inputs=*/unpacked,
-  /*outputType=*/legalTypes, /*originalType=*/origType,
-  currentTypeConverter);
-  remapped.push_back(targetMat);
+ValueVector repl = mapping.lookupOrDefault({operand}, legalTypes);
+if (!repl.empty() && TypeRange(repl) == legalTypes) {
+  // Mapped values have the correct type or there is an existing
+  // materialization. Or the opreand is not mapped at all and has the
+  // correct type.
+  remapped.push_back(repl);

zero9178 wrote:

```suggestion
  remapped.push_back(std::move(repl));
```

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value 
value) {
   return OpBuilder::InsertPoint(insertBlock, insertPt);
 }
 
+/// Helper function that computes an insertion point where the given values are
+/// defined and can be used without a dominance violation.
+static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) {
+  assert(!vals.empty() && "expected at least one value");
+  OpBuilder::InsertPoint pt = computeInsertPoint(vals.front());
+  for (Value v : vals.drop_front())
+pt = chooseLaterInsertPoint(pt, computeInsertPoint(v));
+  return pt;
+}
+
 
//===--===//
 // ConversionValueMapping
 
//===--===//
 
+/// A vector of SSA values, optimized for the most common case of a single
+/// value.
+using ValueVector = SmallVector;
+
 namespace {
+
+/// Helper class to make it possible to use `ValueVector` as a key in DenseMap.
+struct ValueVectorMapInfo {
+  static ValueVector getEmptyKey() { return ValueVector{}; }
+  static ValueVector getTombstoneKey() { return ValueVector{}; }
+  static ::llvm::hash_code getHashValue(ValueVector val) {
+return ::llvm::hash_combine_range(val.begin(), val.end());
+  }
+  static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; }
+};
+
 /// This class wraps a IRMapping to provide recursive lookup
 /// functionality, i.e. we will traverse if the mapped value also has a 
mapping.
 struct ConversionValueMapping {
   /// Return "true" if an SSA value is mapped to the given value. May return
   /// false positives.
   bool isMappedTo(Value value) const { return mappedTo.contains(value); }
 
-  /// Lookup the most recently mapped value with the desired type in the
+  /// Lookup the most recently mapped values with the desired types in the
   /// mapping.
   ///
   /// Special cases:
-  /// - If the desired type is "null", simply return the most recently mapped
-  ///   value.
-  /// - If there is no mapping to the desired type, also return the most
-  ///   recently mapped value.
-  /// - If there is no mapping for the given value at all, return the given
-  ///   value.
-  Value lookupOrDefault(Value from, Type desiredType = nullptr) const;
-
-  /// Lookup a mapped value within the map, or return null if a mapping does 
not
-  /// exist. If a mapping exists, this follows the same behavior of
-  /// `lookupOrDefault`.
-  Value lookupOrNull(Value from, Type desiredType = nullptr) const;
+  /// - If the desired type range is empty, simply return the most recently
+  ///   mapped values.
+  /// - If there is no mapping to the desired types, also return the most
+  ///   recently mapped values.
+  /// - If there is no mapping for the given values at all, return the given
+  ///   values.
+  ValueVector lookupOrDefault(ValueVector from,
+  TypeRange desiredTypes = {}) const;
+
+  /// Lookup the given values within the map, or return an empty vector if the
+  /// values are not mapped. If they are mapped, this follows the same behavior
+  /// as `lookupOrDefault`.
+  ValueVector lookupOrNull(const ValueVector &from,
+   TypeRange desiredTypes = {}) const;
 
   /// Map a value to the one provided.
-  void map(Value oldVal, Value newVal) {
+  void map(const ValueVector &oldVal, const ValueVector &newVal) {
 LLVM_DEBUG({
-  for (Value it = newVal; it; it = mapping.lookupOrNull(it))
-assert(it != oldVal && "inserting cyclic mapping");
+  ValueVector next = newVal;
+  while (true) {
+assert(next != oldVal && "inserting cyclic mapping");
+auto it = mapping.find(next);
+if (it == mapping.end())
+  break;
+next = it->second;
+  }
 });
-mapping.map(oldVal, newVal);
-mappedTo.insert(newVal);
+mapping[oldVal] = newVal;
+for (Value v : newVal)
+  mappedTo.insert(v);
   }
 
-  /// Drop the last mapping for the given value.
-  void erase(Value value) { mapping.erase(value); }
+  /// Drop the last mapping for the given values.
+  void erase(ValueVector value) { mapping.erase(value); }
 
 private:
   /// Current value mappings.
-  IRMapping mapping;
+  DenseMap mapping;
 
   /// All SSA values that are mapped to. May contain false positives.
   DenseSet mappedTo;
 };
 } // namespace
 
-Value ConversionValueMapping::lookupOrDefault(Value from,
-  Type desiredType) const {
-  // Try to find the deepest value that has the desired type. If there is no
-  // such value, simply return the deepest value.
-  Value desiredValue;
+ValueVector
+ConversionValueMapping::lookupOrDefault(ValueVector from,
+TypeRange desiredTypes) const {
+  // Try to find the deepest values that have the desired types. If there is no
+  // such mapping, simply return the deepest values.
+  ValueVe

[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1478,34 +1497,12 @@ Value 
ConversionPatternRewriterImpl::findOrBuildReplacementValue(
   }
   Value castValue = buildUnresolvedMaterialization(
   MaterializationKind::Source, computeInsertPoint(repl), value.getLoc(),
-  /*valueToMap=*/value, /*inputs=*/repl, /*outputType=*/value.getType(),
-  /*originalType=*/Type(), converter);
-  mapping.map(value, castValue);
+  /*valuesToMap=*/{value}, /*inputs=*/repl, /*outputType=*/value.getType(),
+  /*originalType=*/Type(), converter)[0];

zero9178 wrote:

```suggestion
  /*originalType=*/Type(), converter).front();
```

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1192,51 +1256,28 @@ LogicalResult 
ConversionPatternRewriterImpl::remapValues(
   });
   return failure();
 }
-
 // If a type is converted to 0 types, there is nothing to do.
 if (legalTypes.empty()) {
   remapped.push_back({});
   continue;
 }
 
-if (legalTypes.size() != 1) {
-  // TODO: This is a 1:N conversion. The conversion value mapping does not
-  // store such materializations yet. If the types of the most recently
-  // mapped values do not match, build a target materialization.
-  ValueRange unpackedRange(unpacked);
-  if (TypeRange(unpackedRange) == legalTypes) {
-remapped.push_back(std::move(unpacked));
-continue;
-  }
-
-  // Insert a target materialization if the current pattern expects
-  // different legalized types.
-  ValueRange targetMat = buildUnresolvedMaterialization(
-  MaterializationKind::Target, computeInsertPoint(repl), operandLoc,
-  /*valueToMap=*/Value(), /*inputs=*/unpacked,
-  /*outputType=*/legalTypes, /*originalType=*/origType,
-  currentTypeConverter);
-  remapped.push_back(targetMat);
+ValueVector repl = mapping.lookupOrDefault({operand}, legalTypes);
+if (!repl.empty() && TypeRange(repl) == legalTypes) {
+  // Mapped values have the correct type or there is an existing
+  // materialization. Or the opreand is not mapped at all and has the

zero9178 wrote:

```suggestion
  // materialization. Or the operand is not mapped at all and has the
```

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value 
value) {
   return OpBuilder::InsertPoint(insertBlock, insertPt);
 }
 
+/// Helper function that computes an insertion point where the given values are
+/// defined and can be used without a dominance violation.
+static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) {
+  assert(!vals.empty() && "expected at least one value");
+  OpBuilder::InsertPoint pt = computeInsertPoint(vals.front());
+  for (Value v : vals.drop_front())
+pt = chooseLaterInsertPoint(pt, computeInsertPoint(v));
+  return pt;
+}
+
 
//===--===//
 // ConversionValueMapping
 
//===--===//
 
+/// A vector of SSA values, optimized for the most common case of a single
+/// value.
+using ValueVector = SmallVector;
+
 namespace {
+
+/// Helper class to make it possible to use `ValueVector` as a key in DenseMap.
+struct ValueVectorMapInfo {
+  static ValueVector getEmptyKey() { return ValueVector{}; }
+  static ValueVector getTombstoneKey() { return ValueVector{}; }
+  static ::llvm::hash_code getHashValue(ValueVector val) {
+return ::llvm::hash_combine_range(val.begin(), val.end());
+  }
+  static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; }
+};
+
 /// This class wraps a IRMapping to provide recursive lookup
 /// functionality, i.e. we will traverse if the mapped value also has a 
mapping.
 struct ConversionValueMapping {
   /// Return "true" if an SSA value is mapped to the given value. May return
   /// false positives.
   bool isMappedTo(Value value) const { return mappedTo.contains(value); }
 
-  /// Lookup the most recently mapped value with the desired type in the
+  /// Lookup the most recently mapped values with the desired types in the
   /// mapping.
   ///
   /// Special cases:
-  /// - If the desired type is "null", simply return the most recently mapped
-  ///   value.
-  /// - If there is no mapping to the desired type, also return the most
-  ///   recently mapped value.
-  /// - If there is no mapping for the given value at all, return the given
-  ///   value.
-  Value lookupOrDefault(Value from, Type desiredType = nullptr) const;
-
-  /// Lookup a mapped value within the map, or return null if a mapping does 
not
-  /// exist. If a mapping exists, this follows the same behavior of
-  /// `lookupOrDefault`.
-  Value lookupOrNull(Value from, Type desiredType = nullptr) const;
+  /// - If the desired type range is empty, simply return the most recently
+  ///   mapped values.
+  /// - If there is no mapping to the desired types, also return the most
+  ///   recently mapped values.
+  /// - If there is no mapping for the given values at all, return the given
+  ///   values.
+  ValueVector lookupOrDefault(ValueVector from,
+  TypeRange desiredTypes = {}) const;
+
+  /// Lookup the given values within the map, or return an empty vector if the
+  /// values are not mapped. If they are mapped, this follows the same behavior
+  /// as `lookupOrDefault`.
+  ValueVector lookupOrNull(const ValueVector &from,
+   TypeRange desiredTypes = {}) const;
 
   /// Map a value to the one provided.
-  void map(Value oldVal, Value newVal) {
+  void map(const ValueVector &oldVal, const ValueVector &newVal) {
 LLVM_DEBUG({
-  for (Value it = newVal; it; it = mapping.lookupOrNull(it))
-assert(it != oldVal && "inserting cyclic mapping");
+  ValueVector next = newVal;
+  while (true) {
+assert(next != oldVal && "inserting cyclic mapping");
+auto it = mapping.find(next);
+if (it == mapping.end())
+  break;
+next = it->second;
+  }
 });
-mapping.map(oldVal, newVal);
-mappedTo.insert(newVal);
+mapping[oldVal] = newVal;
+for (Value v : newVal)
+  mappedTo.insert(v);
   }
 
-  /// Drop the last mapping for the given value.
-  void erase(Value value) { mapping.erase(value); }
+  /// Drop the last mapping for the given values.
+  void erase(ValueVector value) { mapping.erase(value); }
 
 private:
   /// Current value mappings.
-  IRMapping mapping;
+  DenseMap mapping;
 
   /// All SSA values that are mapped to. May contain false positives.
   DenseSet mappedTo;
 };
 } // namespace
 
-Value ConversionValueMapping::lookupOrDefault(Value from,
-  Type desiredType) const {
-  // Try to find the deepest value that has the desired type. If there is no
-  // such value, simply return the deepest value.
-  Value desiredValue;
+ValueVector
+ConversionValueMapping::lookupOrDefault(ValueVector from,
+TypeRange desiredTypes) const {
+  // Try to find the deepest values that have the desired types. If there is no
+  // such mapping, simply return the deepest values.
+  ValueVe

[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1478,34 +1497,12 @@ Value 
ConversionPatternRewriterImpl::findOrBuildReplacementValue(
   }
   Value castValue = buildUnresolvedMaterialization(
   MaterializationKind::Source, computeInsertPoint(repl), value.getLoc(),

zero9178 wrote:

```suggestion
  MaterializationKind::Source, computeInsertPoint(value), value.getLoc(),
```
I believe (at least for the current callers of `findOrBuildReplacementValue`) 
that this should be sound.
Alternatively, I think an insertion point should be passed as argument as all 
callers should have enough context to have a suitable insertion point which 
avoids the new `computeInsertionPoint` overload. This would be very desireable 
IMO

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value 
value) {
   return OpBuilder::InsertPoint(insertBlock, insertPt);
 }
 
+/// Helper function that computes an insertion point where the given values are
+/// defined and can be used without a dominance violation.
+static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) {
+  assert(!vals.empty() && "expected at least one value");
+  OpBuilder::InsertPoint pt = computeInsertPoint(vals.front());
+  for (Value v : vals.drop_front())
+pt = chooseLaterInsertPoint(pt, computeInsertPoint(v));
+  return pt;
+}
+
 
//===--===//
 // ConversionValueMapping
 
//===--===//
 
+/// A vector of SSA values, optimized for the most common case of a single
+/// value.
+using ValueVector = SmallVector;
+
 namespace {
+
+/// Helper class to make it possible to use `ValueVector` as a key in DenseMap.
+struct ValueVectorMapInfo {
+  static ValueVector getEmptyKey() { return ValueVector{}; }
+  static ValueVector getTombstoneKey() { return ValueVector{}; }
+  static ::llvm::hash_code getHashValue(ValueVector val) {
+return ::llvm::hash_combine_range(val.begin(), val.end());
+  }
+  static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; }
+};
+
 /// This class wraps a IRMapping to provide recursive lookup
 /// functionality, i.e. we will traverse if the mapped value also has a 
mapping.
 struct ConversionValueMapping {
   /// Return "true" if an SSA value is mapped to the given value. May return
   /// false positives.
   bool isMappedTo(Value value) const { return mappedTo.contains(value); }
 
-  /// Lookup the most recently mapped value with the desired type in the
+  /// Lookup the most recently mapped values with the desired types in the
   /// mapping.
   ///
   /// Special cases:
-  /// - If the desired type is "null", simply return the most recently mapped
-  ///   value.
-  /// - If there is no mapping to the desired type, also return the most
-  ///   recently mapped value.
-  /// - If there is no mapping for the given value at all, return the given
-  ///   value.
-  Value lookupOrDefault(Value from, Type desiredType = nullptr) const;
-
-  /// Lookup a mapped value within the map, or return null if a mapping does 
not
-  /// exist. If a mapping exists, this follows the same behavior of
-  /// `lookupOrDefault`.
-  Value lookupOrNull(Value from, Type desiredType = nullptr) const;
+  /// - If the desired type range is empty, simply return the most recently
+  ///   mapped values.
+  /// - If there is no mapping to the desired types, also return the most
+  ///   recently mapped values.
+  /// - If there is no mapping for the given values at all, return the given
+  ///   values.
+  ValueVector lookupOrDefault(ValueVector from,
+  TypeRange desiredTypes = {}) const;
+
+  /// Lookup the given values within the map, or return an empty vector if the
+  /// values are not mapped. If they are mapped, this follows the same behavior
+  /// as `lookupOrDefault`.
+  ValueVector lookupOrNull(const ValueVector &from,
+   TypeRange desiredTypes = {}) const;
 
   /// Map a value to the one provided.
-  void map(Value oldVal, Value newVal) {
+  void map(const ValueVector &oldVal, const ValueVector &newVal) {
 LLVM_DEBUG({
-  for (Value it = newVal; it; it = mapping.lookupOrNull(it))
-assert(it != oldVal && "inserting cyclic mapping");
+  ValueVector next = newVal;
+  while (true) {
+assert(next != oldVal && "inserting cyclic mapping");
+auto it = mapping.find(next);
+if (it == mapping.end())
+  break;
+next = it->second;
+  }
 });
-mapping.map(oldVal, newVal);
-mappedTo.insert(newVal);
+mapping[oldVal] = newVal;
+for (Value v : newVal)
+  mappedTo.insert(v);
   }
 
-  /// Drop the last mapping for the given value.
-  void erase(Value value) { mapping.erase(value); }
+  /// Drop the last mapping for the given values.
+  void erase(ValueVector value) { mapping.erase(value); }
 
 private:
   /// Current value mappings.
-  IRMapping mapping;
+  DenseMap mapping;
 
   /// All SSA values that are mapped to. May contain false positives.
   DenseSet mappedTo;
 };
 } // namespace
 
-Value ConversionValueMapping::lookupOrDefault(Value from,
-  Type desiredType) const {
-  // Try to find the deepest value that has the desired type. If there is no
-  // such value, simply return the deepest value.
-  Value desiredValue;
+ValueVector
+ConversionValueMapping::lookupOrDefault(ValueVector from,
+TypeRange desiredTypes) const {
+  // Try to find the deepest values that have the desired types. If there is no
+  // such mapping, simply return the deepest values.
+  ValueVe

[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1101,18 +1172,18 @@ void CreateOperationRewrite::rollback() {
 UnresolvedMaterializationRewrite::UnresolvedMaterializationRewrite(
 ConversionPatternRewriterImpl &rewriterImpl, UnrealizedConversionCastOp op,
 const TypeConverter *converter, MaterializationKind kind, Type 
originalType,
-Value mappedValue)
+ValueVector mappedValues)
 : OperationRewrite(Kind::UnresolvedMaterialization, rewriterImpl, op),
   converterAndKind(converter, kind), originalType(originalType),
-  mappedValue(mappedValue) {
+  mappedValues(mappedValues) {

zero9178 wrote:

```suggestion
mappedValues(std::move(mappedValues)) {
```

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -63,80 +113,140 @@ static OpBuilder::InsertPoint computeInsertPoint(Value 
value) {
   return OpBuilder::InsertPoint(insertBlock, insertPt);
 }
 
+/// Helper function that computes an insertion point where the given values are
+/// defined and can be used without a dominance violation.
+static OpBuilder::InsertPoint computeInsertPoint(ArrayRef vals) {
+  assert(!vals.empty() && "expected at least one value");
+  OpBuilder::InsertPoint pt = computeInsertPoint(vals.front());
+  for (Value v : vals.drop_front())
+pt = chooseLaterInsertPoint(pt, computeInsertPoint(v));
+  return pt;
+}
+
 
//===--===//
 // ConversionValueMapping
 
//===--===//
 
+/// A vector of SSA values, optimized for the most common case of a single
+/// value.
+using ValueVector = SmallVector;
+
 namespace {
+
+/// Helper class to make it possible to use `ValueVector` as a key in DenseMap.
+struct ValueVectorMapInfo {
+  static ValueVector getEmptyKey() { return ValueVector{}; }
+  static ValueVector getTombstoneKey() { return ValueVector{}; }
+  static ::llvm::hash_code getHashValue(ValueVector val) {
+return ::llvm::hash_combine_range(val.begin(), val.end());
+  }
+  static bool isEqual(ValueVector LHS, ValueVector RHS) { return LHS == RHS; }
+};
+
 /// This class wraps a IRMapping to provide recursive lookup
 /// functionality, i.e. we will traverse if the mapped value also has a 
mapping.
 struct ConversionValueMapping {
   /// Return "true" if an SSA value is mapped to the given value. May return
   /// false positives.
   bool isMappedTo(Value value) const { return mappedTo.contains(value); }
 
-  /// Lookup the most recently mapped value with the desired type in the
+  /// Lookup the most recently mapped values with the desired types in the
   /// mapping.
   ///
   /// Special cases:
-  /// - If the desired type is "null", simply return the most recently mapped
-  ///   value.
-  /// - If there is no mapping to the desired type, also return the most
-  ///   recently mapped value.
-  /// - If there is no mapping for the given value at all, return the given
-  ///   value.
-  Value lookupOrDefault(Value from, Type desiredType = nullptr) const;
-
-  /// Lookup a mapped value within the map, or return null if a mapping does 
not
-  /// exist. If a mapping exists, this follows the same behavior of
-  /// `lookupOrDefault`.
-  Value lookupOrNull(Value from, Type desiredType = nullptr) const;
+  /// - If the desired type range is empty, simply return the most recently
+  ///   mapped values.
+  /// - If there is no mapping to the desired types, also return the most
+  ///   recently mapped values.
+  /// - If there is no mapping for the given values at all, return the given
+  ///   values.
+  ValueVector lookupOrDefault(ValueVector from,
+  TypeRange desiredTypes = {}) const;
+
+  /// Lookup the given values within the map, or return an empty vector if the
+  /// values are not mapped. If they are mapped, this follows the same behavior
+  /// as `lookupOrDefault`.
+  ValueVector lookupOrNull(const ValueVector &from,
+   TypeRange desiredTypes = {}) const;

zero9178 wrote:

Neither of these two functions are ever called with more than just a single 
`Value`. Could we change the parameters accordingly?

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1423,37 +1458,21 @@ ValueRange 
ConversionPatternRewriterImpl::buildUnresolvedMaterialization(
   builder.setInsertionPoint(ip.getBlock(), ip.getPoint());
   auto convertOp =
   builder.create(loc, outputTypes, inputs);
-  if (valueToMap) {
-assert(outputTypes.size() == 1 && "1:N mapping is not supported");
-mapping.map(valueToMap, convertOp.getResult(0));
-  }
+  if (!valuesToMap.empty())
+mapping.map(valuesToMap, convertOp.getResults());
   if (castOp)
 *castOp = convertOp;
   appendRewrite(convertOp, converter, kind,
-  originalType, valueToMap);
+  originalType, valuesToMap);

zero9178 wrote:

```suggestion
  originalType, 
std::move(valuesToMap));
```

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] [mlir] [mlir][Transforms] Support 1:N mappings in `ConversionValueMapping` (PR #116524)

2024-12-21 Thread Markus Böck via llvm-branch-commits


@@ -1192,51 +1256,28 @@ LogicalResult 
ConversionPatternRewriterImpl::remapValues(
   });
   return failure();
 }
-
 // If a type is converted to 0 types, there is nothing to do.
 if (legalTypes.empty()) {
   remapped.push_back({});
   continue;
 }
 
-if (legalTypes.size() != 1) {
-  // TODO: This is a 1:N conversion. The conversion value mapping does not
-  // store such materializations yet. If the types of the most recently
-  // mapped values do not match, build a target materialization.
-  ValueRange unpackedRange(unpacked);
-  if (TypeRange(unpackedRange) == legalTypes) {
-remapped.push_back(std::move(unpacked));
-continue;
-  }
-
-  // Insert a target materialization if the current pattern expects
-  // different legalized types.
-  ValueRange targetMat = buildUnresolvedMaterialization(
-  MaterializationKind::Target, computeInsertPoint(repl), operandLoc,
-  /*valueToMap=*/Value(), /*inputs=*/unpacked,
-  /*outputType=*/legalTypes, /*originalType=*/origType,
-  currentTypeConverter);
-  remapped.push_back(targetMat);
+ValueVector repl = mapping.lookupOrDefault({operand}, legalTypes);
+if (!repl.empty() && TypeRange(repl) == legalTypes) {
+  // Mapped values have the correct type or there is an existing
+  // materialization. Or the opreand is not mapped at all and has the
+  // correct type.
+  remapped.push_back(repl);
   continue;
 }
 
-// Handle 1->1 type conversions.
-Type desiredType = legalTypes.front();
-// Try to find a mapped value with the desired type. (Or the operand itself
-// if the value is not mapped at all.)
-Value newOperand = mapping.lookupOrDefault(operand, desiredType);
-if (newOperand.getType() != desiredType) {
-  // If the looked up value's type does not have the desired type, it means
-  // that the value was replaced with a value of different type and no
-  // target materialization was created yet.
-  Value castValue = buildUnresolvedMaterialization(
-  MaterializationKind::Target, computeInsertPoint(newOperand),
-  operandLoc, /*valueToMap=*/newOperand, /*inputs=*/unpacked,
-  /*outputType=*/desiredType, /*originalType=*/origType,
-  currentTypeConverter);
-  newOperand = castValue;
-}
-remapped.push_back({newOperand});
+// Create a materialization for the most recently mapped values.
+repl = mapping.lookupOrDefault({operand});
+ValueRange castValues = buildUnresolvedMaterialization(
+MaterializationKind::Target, computeInsertPoint(repl), operandLoc,

zero9178 wrote:

```suggestion
MaterializationKind::Target, rewriter.saveInsertionPoint(), operandLoc,
```
Using the insertion point from pattern rewriter makes more sense to me here and 
is simpler:
* For the caller in `ConversionPattern::matchAndRewrite` it is guaranteed to be 
a valid insertion point where the operands are reachable
* For `getRemappedValue[s]` the user expectation is likely that the current 
insertion point would be used for any materializations that occur

https://github.com/llvm/llvm-project/pull/116524
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits