Skip to content

Commit 607afa0

Browse files
authored
Revert "[llvm][IR] Extend BranchWeightMetadata to track provenance of weights" (#95060)
Reverts #86609 This change causes compile-time regressions for stage2 builds (https://llvm-compile-time-tracker.com/compare.php?from=3254f31a66263ea9647c9547f1531c3123444fcd&to=c5978f1eb5eeca8610b9dfce1fcbf1f473911cd8&stat=instructions:u). It also introduced unintended changes to `.text` which should be addressed before relanding.
1 parent 41c650e commit 607afa0

30 files changed

+88
-169
lines changed

clang/test/CodeGenCXX/attr-likelihood-if-vs-builtin-expect.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,5 +221,5 @@ void tu2(int &i) {
221221
}
222222
}
223223

224-
// CHECK: [[BW_LIKELY]] = !{!"branch_weights", !"expected", i32 2000, i32 1}
225-
// CHECK: [[BW_UNLIKELY]] = !{!"branch_weights", !"expected", i32 1, i32 2000}
224+
// CHECK: [[BW_LIKELY]] = !{!"branch_weights", i32 2000, i32 1}
225+
// CHECK: [[BW_UNLIKELY]] = !{!"branch_weights", i32 1, i32 2000}

llvm/docs/BranchWeightMetadata.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,11 @@ Supported Instructions
2828

2929
Metadata is only assigned to the conditional branches. There are two extra
3030
operands for the true and the false branch.
31-
We optionally track if the metadata was added by ``__builtin_expect`` or
32-
``__builtin_expect_with_probability`` with an optional field ``!"expected"``.
3331

3432
.. code-block:: none
3533
3634
!0 = !{
3735
!"branch_weights",
38-
[ !"expected", ]
3936
i32 <TRUE_BRANCH_WEIGHT>,
4037
i32 <FALSE_BRANCH_WEIGHT>
4138
}
@@ -50,7 +47,6 @@ is always case #0).
5047
5148
!0 = !{
5249
!"branch_weights",
53-
[ !"expected", ]
5450
i32 <DEFAULT_BRANCH_WEIGHT>
5551
[ , i32 <CASE_BRANCH_WEIGHT> ... ]
5652
}
@@ -64,7 +60,6 @@ Branch weights are assigned to every destination.
6460
6561
!0 = !{
6662
!"branch_weights",
67-
[ !"expected", ]
6863
i32 <LABEL_BRANCH_WEIGHT>
6964
[ , i32 <LABEL_BRANCH_WEIGHT> ... ]
7065
}
@@ -80,7 +75,6 @@ block and entry counts which may not be accurate with sampling.
8075
8176
!0 = !{
8277
!"branch_weights",
83-
[ !"expected", ]
8478
i32 <CALL_BRANCH_WEIGHT>
8579
}
8680
@@ -101,7 +95,6 @@ is used.
10195
10296
!0 = !{
10397
!"branch_weights",
104-
[ !"expected", ]
10598
i32 <INVOKE_NORMAL_WEIGHT>
10699
[ , i32 <INVOKE_UNWIND_WEIGHT> ]
107100
}

llvm/include/llvm/IR/MDBuilder.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ class MDBuilder {
5959
//===------------------------------------------------------------------===//
6060

6161
/// Return metadata containing two branch weights.
62-
/// @param TrueWeight the weight of the true branch
63-
/// @param FalseWeight the weight of the false branch
64-
/// @param Do these weights come from __builtin_expect*
65-
MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight,
66-
bool IsExpected = false);
62+
MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight);
6763

6864
/// Return metadata containing two branch weights, with significant bias
6965
/// towards `true` destination.
@@ -74,10 +70,7 @@ class MDBuilder {
7470
MDNode *createUnlikelyBranchWeights();
7571

7672
/// Return metadata containing a number of branch weights.
77-
/// @param Weights the weights of all the branches
78-
/// @param Do these weights come from __builtin_expect*
79-
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights,
80-
bool IsExpected = false);
73+
MDNode *createBranchWeights(ArrayRef<uint32_t> Weights);
8174

8275
/// Return metadata specifying that a branch or switch is unpredictable.
8376
MDNode *createUnpredictable();

llvm/include/llvm/IR/ProfDataUtils.h

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,6 @@ MDNode *getBranchWeightMDNode(const Instruction &I);
5555
/// Nullptr otherwise.
5656
MDNode *getValidBranchWeightMDNode(const Instruction &I);
5757

58-
/// Check if Branch Weight Metadata has an "expected" field from an llvm.expect*
59-
/// intrinsic
60-
bool hasBranchWeightOrigin(const Instruction &I);
61-
62-
/// Check if Branch Weight Metadata has an "expected" field from an llvm.expect*
63-
/// intrinsic
64-
bool hasBranchWeightOrigin(const MDNode *ProfileData);
65-
66-
/// Return the offset to the first branch weight data
67-
unsigned getBranchWeightOffset(const MDNode *ProfileData);
68-
6958
/// Extract branch weights from MD_prof metadata
7059
///
7160
/// \param ProfileData A pointer to an MDNode.
@@ -122,11 +111,7 @@ bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalWeights);
122111

123112
/// Create a new `branch_weights` metadata node and add or overwrite
124113
/// a `prof` metadata reference to instruction `I`.
125-
/// \param I the Instruction to set branch weights on.
126-
/// \param Weights an array of weights to set on instruction I.
127-
/// \param IsExpected were these weights added from an llvm.expect* intrinsic.
128-
void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights,
129-
bool IsExpected);
114+
void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights);
130115

131116
/// Scaling the profile data attached to 'I' using the ratio of S/T.
132117
void scaleProfData(Instruction &I, uint64_t S, uint64_t T);

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8866,8 +8866,7 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, ModifyDT &ModifiedDT) {
88668866
scaleWeights(NewTrueWeight, NewFalseWeight);
88678867
Br1->setMetadata(LLVMContext::MD_prof,
88688868
MDBuilder(Br1->getContext())
8869-
.createBranchWeights(TrueWeight, FalseWeight,
8870-
hasBranchWeightOrigin(*Br1)));
8869+
.createBranchWeights(TrueWeight, FalseWeight));
88718870

88728871
NewTrueWeight = TrueWeight;
88738872
NewFalseWeight = 2 * FalseWeight;

llvm/lib/IR/Instruction.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,23 +1268,12 @@ Instruction *Instruction::cloneImpl() const {
12681268

12691269
void Instruction::swapProfMetadata() {
12701270
MDNode *ProfileData = getBranchWeightMDNode(*this);
1271-
if (!ProfileData)
1272-
return;
1273-
unsigned FirstIdx = getBranchWeightOffset(ProfileData);
1274-
if (ProfileData->getNumOperands() != 2 + FirstIdx)
1271+
if (!ProfileData || ProfileData->getNumOperands() != 3)
12751272
return;
12761273

1277-
unsigned SecondIdx = FirstIdx + 1;
1278-
SmallVector<Metadata *, 4> Ops;
1279-
// If there are more weights past the second, we can't swap them
1280-
if (ProfileData->getNumOperands() > SecondIdx + 1)
1281-
return;
1282-
for (unsigned Idx = 0; Idx < FirstIdx; ++Idx) {
1283-
Ops.push_back(ProfileData->getOperand(Idx));
1284-
}
1285-
// Switch the order of the weights
1286-
Ops.push_back(ProfileData->getOperand(SecondIdx));
1287-
Ops.push_back(ProfileData->getOperand(FirstIdx));
1274+
// The first operand is the name. Fetch them backwards and build a new one.
1275+
Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
1276+
ProfileData->getOperand(1)};
12881277
setMetadata(LLVMContext::MD_prof,
12891278
MDNode::get(ProfileData->getContext(), Ops));
12901279
}

llvm/lib/IR/Instructions.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5199,11 +5199,7 @@ void SwitchInstProfUpdateWrapper::init() {
51995199
if (!ProfileData)
52005200
return;
52015201

5202-
// FIXME: This check belongs in ProfDataUtils. Its almost equivalent to
5203-
// getValidBranchWeightMDNode(), but the need to use llvm_unreachable
5204-
// makes them slightly different.
5205-
if (ProfileData->getNumOperands() !=
5206-
SI.getNumSuccessors() + getBranchWeightOffset(ProfileData)) {
5202+
if (ProfileData->getNumOperands() != SI.getNumSuccessors() + 1) {
52075203
llvm_unreachable("number of prof branch_weights metadata operands does "
52085204
"not correspond to number of succesors");
52095205
}

llvm/lib/IR/MDBuilder.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ MDNode *MDBuilder::createFPMath(float Accuracy) {
3535
}
3636

3737
MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
38-
uint32_t FalseWeight, bool IsExpected) {
39-
return createBranchWeights({TrueWeight, FalseWeight}, IsExpected);
38+
uint32_t FalseWeight) {
39+
return createBranchWeights({TrueWeight, FalseWeight});
4040
}
4141

4242
MDNode *MDBuilder::createLikelyBranchWeights() {
@@ -49,19 +49,15 @@ MDNode *MDBuilder::createUnlikelyBranchWeights() {
4949
return createBranchWeights(1, (1U << 20) - 1);
5050
}
5151

52-
MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights,
53-
bool IsExpected) {
52+
MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
5453
assert(Weights.size() >= 1 && "Need at least one branch weights!");
5554

56-
unsigned int Offset = IsExpected ? 2 : 1;
57-
SmallVector<Metadata *, 4> Vals(Weights.size() + Offset);
55+
SmallVector<Metadata *, 4> Vals(Weights.size() + 1);
5856
Vals[0] = createString("branch_weights");
59-
if (IsExpected)
60-
Vals[1] = createString("expected");
6157

6258
Type *Int32Ty = Type::getInt32Ty(Context);
6359
for (unsigned i = 0, e = Weights.size(); i != e; ++i)
64-
Vals[i + Offset] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));
60+
Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));
6561

6662
return MDNode::get(Context, Vals);
6763
}

llvm/lib/IR/Metadata.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,10 +1196,10 @@ MDNode *MDNode::mergeDirectCallProfMetadata(MDNode *A, MDNode *B,
11961196
StringRef AProfName = AMDS->getString();
11971197
StringRef BProfName = BMDS->getString();
11981198
if (AProfName == "branch_weights" && BProfName == "branch_weights") {
1199-
ConstantInt *AInstrWeight = mdconst::dyn_extract<ConstantInt>(
1200-
A->getOperand(getBranchWeightOffset(A)));
1201-
ConstantInt *BInstrWeight = mdconst::dyn_extract<ConstantInt>(
1202-
B->getOperand(getBranchWeightOffset(B)));
1199+
ConstantInt *AInstrWeight =
1200+
mdconst::dyn_extract<ConstantInt>(A->getOperand(1));
1201+
ConstantInt *BInstrWeight =
1202+
mdconst::dyn_extract<ConstantInt>(B->getOperand(1));
12031203
assert(AInstrWeight && BInstrWeight && "verified by LLVM verifier");
12041204
return MDNode::get(Ctx,
12051205
{MDHelper.createString("branch_weights"),

llvm/lib/IR/ProfDataUtils.cpp

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ namespace {
4040
// We maintain some constants here to ensure that we access the branch weights
4141
// correctly, and can change the behavior in the future if the layout changes
4242

43+
// The index at which the weights vector starts
44+
constexpr unsigned WeightsIdx = 1;
45+
4346
// the minimum number of operands for MD_prof nodes with branch weights
4447
constexpr unsigned MinBWOps = 3;
4548

@@ -72,16 +75,15 @@ static void extractFromBranchWeightMD(const MDNode *ProfileData,
7275
assert(isBranchWeightMD(ProfileData) && "wrong metadata");
7376

7477
unsigned NOps = ProfileData->getNumOperands();
75-
unsigned WeightsIdx = getBranchWeightOffset(ProfileData);
7678
assert(WeightsIdx < NOps && "Weights Index must be less than NOps.");
7779
Weights.resize(NOps - WeightsIdx);
7880

7981
for (unsigned Idx = WeightsIdx, E = NOps; Idx != E; ++Idx) {
8082
ConstantInt *Weight =
8183
mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx));
8284
assert(Weight && "Malformed branch_weight in MD_prof node");
83-
assert(Weight->getValue().getActiveBits() <= (sizeof(T) * 8) &&
84-
"Too many bits for MD_prof branch_weight");
85+
assert(Weight->getValue().getActiveBits() <= 32 &&
86+
"Too many bits for uint32_t");
8587
Weights[Idx - WeightsIdx] = Weight->getZExtValue();
8688
}
8789
}
@@ -121,26 +123,6 @@ bool hasValidBranchWeightMD(const Instruction &I) {
121123
return getValidBranchWeightMDNode(I);
122124
}
123125

124-
bool hasBranchWeightOrigin(const Instruction &I) {
125-
auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
126-
return hasBranchWeightOrigin(ProfileData);
127-
}
128-
129-
bool hasBranchWeightOrigin(const MDNode *ProfileData) {
130-
if (!isBranchWeightMD(ProfileData))
131-
return false;
132-
auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(1));
133-
// NOTE: if we ever have more types of branch weight provenance,
134-
// we need to check the string value is "expected". For now, we
135-
// supply a more generic API, and avoid the spurious comparisons.
136-
assert(ProfDataName == nullptr || ProfDataName->getString() == "expected");
137-
return ProfDataName != nullptr;
138-
}
139-
140-
unsigned getBranchWeightOffset(const MDNode *ProfileData) {
141-
return hasBranchWeightOrigin(ProfileData) ? 2 : 1;
142-
}
143-
144126
MDNode *getBranchWeightMDNode(const Instruction &I) {
145127
auto *ProfileData = I.getMetadata(LLVMContext::MD_prof);
146128
if (!isBranchWeightMD(ProfileData))
@@ -150,9 +132,7 @@ MDNode *getBranchWeightMDNode(const Instruction &I) {
150132

151133
MDNode *getValidBranchWeightMDNode(const Instruction &I) {
152134
auto *ProfileData = getBranchWeightMDNode(I);
153-
auto Offset = getBranchWeightOffset(ProfileData);
154-
if (ProfileData &&
155-
ProfileData->getNumOperands() == Offset + I.getNumSuccessors())
135+
if (ProfileData && ProfileData->getNumOperands() == 1 + I.getNumSuccessors())
156136
return ProfileData;
157137
return nullptr;
158138
}
@@ -211,8 +191,7 @@ bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalVal) {
211191
return false;
212192

213193
if (ProfDataName->getString() == "branch_weights") {
214-
unsigned Offset = getBranchWeightOffset(ProfileData);
215-
for (unsigned Idx = Offset; Idx < ProfileData->getNumOperands(); ++Idx) {
194+
for (unsigned Idx = 1; Idx < ProfileData->getNumOperands(); Idx++) {
216195
auto *V = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx));
217196
assert(V && "Malformed branch_weight in MD_prof node");
218197
TotalVal += V->getValue().getZExtValue();
@@ -233,10 +212,9 @@ bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalVal) {
233212
return extractProfTotalWeight(I.getMetadata(LLVMContext::MD_prof), TotalVal);
234213
}
235214

236-
void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights,
237-
bool IsExpected) {
215+
void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights) {
238216
MDBuilder MDB(I.getContext());
239-
MDNode *BranchWeights = MDB.createBranchWeights(Weights, IsExpected);
217+
MDNode *BranchWeights = MDB.createBranchWeights(Weights);
240218
I.setMetadata(LLVMContext::MD_prof, BranchWeights);
241219
}
242220

llvm/lib/IR/Verifier.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@
104104
#include "llvm/IR/Module.h"
105105
#include "llvm/IR/ModuleSlotTracker.h"
106106
#include "llvm/IR/PassManager.h"
107-
#include "llvm/IR/ProfDataUtils.h"
108107
#include "llvm/IR/Statepoint.h"
109108
#include "llvm/IR/Type.h"
110109
#include "llvm/IR/Use.h"
@@ -4809,10 +4808,8 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
48094808

48104809
// Check consistency of !prof branch_weights metadata.
48114810
if (ProfName == "branch_weights") {
4812-
unsigned int Offset = getBranchWeightOffset(MD);
48134811
if (isa<InvokeInst>(&I)) {
4814-
Check(MD->getNumOperands() == (1 + Offset) ||
4815-
MD->getNumOperands() == (2 + Offset),
4812+
Check(MD->getNumOperands() == 2 || MD->getNumOperands() == 3,
48164813
"Wrong number of InvokeInst branch_weights operands", MD);
48174814
} else {
48184815
unsigned ExpectedNumOperands = 0;
@@ -4832,10 +4829,10 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) {
48324829
CheckFailed("!prof branch_weights are not allowed for this instruction",
48334830
MD);
48344831

4835-
Check(MD->getNumOperands() == Offset + ExpectedNumOperands,
4832+
Check(MD->getNumOperands() == 1 + ExpectedNumOperands,
48364833
"Wrong number of operands", MD);
48374834
}
4838-
for (unsigned i = Offset; i < MD->getNumOperands(); ++i) {
4835+
for (unsigned i = 1; i < MD->getNumOperands(); ++i) {
48394836
auto &MDO = MD->getOperand(i);
48404837
Check(MDO, "second operand should not be null", MD);
48414838
Check(mdconst::dyn_extract<ConstantInt>(MDO),

llvm/lib/Transforms/IPO/SampleProfile.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,8 +1662,7 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) {
16621662
else if (OverwriteExistingWeights)
16631663
I.setMetadata(LLVMContext::MD_prof, nullptr);
16641664
} else if (!isa<IntrinsicInst>(&I)) {
1665-
setBranchWeights(I, {static_cast<uint32_t>(BlockWeights[BB])},
1666-
/*IsExpected=*/false);
1665+
setBranchWeights(I, {static_cast<uint32_t>(BlockWeights[BB])});
16671666
}
16681667
}
16691668
} else if (OverwriteExistingWeights || ProfileSampleBlockAccurate) {
@@ -1674,7 +1673,7 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) {
16741673
if (cast<CallBase>(I).isIndirectCall()) {
16751674
I.setMetadata(LLVMContext::MD_prof, nullptr);
16761675
} else {
1677-
setBranchWeights(I, {uint32_t(0)}, /*IsExpected=*/false);
1676+
setBranchWeights(I, {uint32_t(0)});
16781677
}
16791678
}
16801679
}
@@ -1757,7 +1756,7 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) {
17571756
if (MaxWeight > 0 &&
17581757
(!TI->extractProfTotalWeight(TempWeight) || OverwriteExistingWeights)) {
17591758
LLVM_DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n");
1760-
setBranchWeights(*TI, Weights, /*IsExpected=*/false);
1759+
setBranchWeights(*TI, Weights);
17611760
ORE->emit([&]() {
17621761
return OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst)
17631762
<< "most popular destination for conditional branches at "

llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1878,7 +1878,7 @@ void CHR::fixupBranchesAndSelects(CHRScope *Scope,
18781878
static_cast<uint32_t>(CHRBranchBias.scale(1000)),
18791879
static_cast<uint32_t>(CHRBranchBias.getCompl().scale(1000)),
18801880
};
1881-
setBranchWeights(*MergedBR, Weights, /*IsExpected=*/false);
1881+
setBranchWeights(*MergedBR, Weights);
18821882
CHR_DEBUG(dbgs() << "CHR branch bias " << Weights[0] << ":" << Weights[1]
18831883
<< "\n");
18841884
}

llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,7 @@ CallBase &llvm::pgo::promoteIndirectCall(CallBase &CB, Function *DirectCallee,
259259
promoteCallWithIfThenElse(CB, DirectCallee, BranchWeights);
260260

261261
if (AttachProfToDirectCall) {
262-
setBranchWeights(NewInst, {static_cast<uint32_t>(Count)},
263-
/*IsExpected=*/false);
262+
setBranchWeights(NewInst, {static_cast<uint32_t>(Count)});
264263
}
265264

266265
using namespace ore;

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,8 +1474,7 @@ void PGOUseFunc::populateCoverage(IndexedInstrProfReader *PGOReader) {
14741474
for (auto *Succ : successors(&BB))
14751475
Weights.push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0);
14761476
if (Weights.size() >= 2)
1477-
llvm::setBranchWeights(*BB.getTerminator(), Weights,
1478-
/*IsExpected=*/false);
1477+
llvm::setBranchWeights(*BB.getTerminator(), Weights);
14791478
}
14801479

14811480
unsigned NumCorruptCoverage = 0;
@@ -2261,7 +2260,7 @@ void llvm::setProfMetadata(Module *M, Instruction *TI,
22612260

22622261
misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false);
22632262

2264-
setBranchWeights(*TI, Weights, /*IsExpected=*/false);
2263+
setBranchWeights(*TI, Weights);
22652264
if (EmitBranchProbability) {
22662265
std::string BrCondStr = getBranchCondString(TI);
22672266
if (BrCondStr.empty())

0 commit comments

Comments
 (0)