Skip to content

Commit 41bcfcd

Browse files
bcardosolopeslanza
authored andcommitted
[CIR][CIRGen][NFC] Cleanups: more boilerplate work for conditional on exceptions
Code path still hits an assert sooner, incremental NFC step.
1 parent d02a8d8 commit 41bcfcd

File tree

3 files changed

+120
-3
lines changed

3 files changed

+120
-3
lines changed

clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class CIRDataLayout {
6262
return getAlignment(ty, true);
6363
}
6464

65+
llvm::Align getPrefTypeAlign(mlir::Type Ty) const {
66+
return getAlignment(Ty, false);
67+
}
68+
6569
/// Returns the maximum number of bytes that may be overwritten by
6670
/// storing the specified type.
6771
///

clang/lib/CIR/CodeGen/CIRGenCleanup.cpp

+72-1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,75 @@ RValue DominatingValue<RValue>::saved_type::restore(CIRGenFunction &CGF) {
115115
llvm_unreachable("bad saved r-value kind");
116116
}
117117

118+
static bool IsUsedAsEHCleanup(EHScopeStack &EHStack,
119+
EHScopeStack::stable_iterator cleanup) {
120+
// If we needed an EH block for any reason, that counts.
121+
if (EHStack.find(cleanup)->hasEHBranches())
122+
return true;
123+
124+
// Check whether any enclosed cleanups were needed.
125+
for (EHScopeStack::stable_iterator i = EHStack.getInnermostEHScope();
126+
i != cleanup;) {
127+
assert(cleanup.strictlyEncloses(i));
128+
129+
EHScope &scope = *EHStack.find(i);
130+
if (scope.hasEHBranches())
131+
return true;
132+
133+
i = scope.getEnclosingEHScope();
134+
}
135+
136+
return false;
137+
}
138+
139+
enum ForActivation_t { ForActivation, ForDeactivation };
140+
141+
/// The given cleanup block is changing activation state. Configure a
142+
/// cleanup variable if necessary.
143+
///
144+
/// It would be good if we had some way of determining if there were
145+
/// extra uses *after* the change-over point.
146+
static void setupCleanupBlockActivation(CIRGenFunction &CGF,
147+
EHScopeStack::stable_iterator C,
148+
ForActivation_t kind,
149+
mlir::Operation *dominatingIP) {
150+
EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack.find(C));
151+
152+
// We always need the flag if we're activating the cleanup in a
153+
// conditional context, because we have to assume that the current
154+
// location doesn't necessarily dominate the cleanup's code.
155+
bool isActivatedInConditional =
156+
(kind == ForActivation && CGF.isInConditionalBranch());
157+
158+
bool needFlag = false;
159+
160+
// Calculate whether the cleanup was used:
161+
162+
// - as a normal cleanup
163+
if (Scope.isNormalCleanup()) {
164+
Scope.setTestFlagInNormalCleanup();
165+
needFlag = true;
166+
}
167+
168+
// - as an EH cleanup
169+
if (Scope.isEHCleanup() &&
170+
(isActivatedInConditional || IsUsedAsEHCleanup(CGF.EHStack, C))) {
171+
Scope.setTestFlagInEHCleanup();
172+
needFlag = true;
173+
}
174+
175+
// If it hasn't yet been used as either, we're done.
176+
if (!needFlag)
177+
return;
178+
179+
Address var = Scope.getActiveFlag();
180+
if (!var.isValid()) {
181+
llvm_unreachable("NYI");
182+
}
183+
184+
llvm_unreachable("NYI");
185+
}
186+
118187
/// Deactive a cleanup that was created in an active state.
119188
void CIRGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
120189
mlir::Operation *dominatingIP) {
@@ -143,7 +212,9 @@ void CIRGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C,
143212
return;
144213
}
145214

146-
llvm_unreachable("NYI");
215+
// Otherwise, follow the general case.
216+
setupCleanupBlockActivation(*this, C, ForDeactivation, dominatingIP);
217+
Scope.setActive(false);
147218
}
148219

149220
void CIRGenFunction::initFullExprCleanupWithFlag(Address ActiveFlag) {

clang/lib/CIR/CodeGen/CIRGenFunction.h

+44-2
Original file line numberDiff line numberDiff line change
@@ -2307,15 +2307,57 @@ struct DominatingCIRValue {
23072307
typedef llvm::PointerIntPair<mlir::Value, 1, bool> saved_type;
23082308

23092309
/// Answer whether the given value needs extra work to be saved.
2310-
static bool needsSaving(mlir::Value value) { llvm_unreachable("NYI"); }
2310+
static bool needsSaving(mlir::Value value) {
2311+
if (!value)
2312+
return false;
2313+
2314+
// If it's a block argument, we don't need to save.
2315+
mlir::Operation *definingOp = value.getDefiningOp();
2316+
if (!definingOp)
2317+
return false;
2318+
2319+
// If value is defined the function or a global init entry block, we don't
2320+
// need to save.
2321+
mlir::Block *currBlock = definingOp->getBlock();
2322+
if (!currBlock->isEntryBlock() || !definingOp->getParentOp())
2323+
return false;
2324+
2325+
if (auto fnOp = definingOp->getParentOfType<mlir::cir::FuncOp>()) {
2326+
if (&fnOp.getBody().front() == currBlock)
2327+
return true;
2328+
return false;
2329+
}
2330+
2331+
if (auto globalOp = definingOp->getParentOfType<mlir::cir::GlobalOp>()) {
2332+
assert(globalOp.getNumRegions() == 2 && "other regions NYI");
2333+
if (&globalOp.getCtorRegion().front() == currBlock)
2334+
return true;
2335+
if (&globalOp.getDtorRegion().front() == currBlock)
2336+
return true;
2337+
return false;
2338+
}
2339+
2340+
return false;
2341+
}
23112342

23122343
static saved_type save(CIRGenFunction &CGF, mlir::Value value);
23132344
static mlir::Value restore(CIRGenFunction &CGF, saved_type value);
23142345
};
23152346

23162347
inline DominatingCIRValue::saved_type
23172348
DominatingCIRValue::save(CIRGenFunction &CGF, mlir::Value value) {
2318-
llvm_unreachable("NYI");
2349+
if (!needsSaving(value))
2350+
return saved_type(value, false);
2351+
2352+
// Otherwise, we need an alloca.
2353+
auto align = CharUnits::fromQuantity(
2354+
CGF.CGM.getDataLayout().getPrefTypeAlign(value.getType()));
2355+
mlir::Location loc = value.getLoc();
2356+
Address alloca =
2357+
CGF.CreateTempAlloca(value.getType(), align, loc, "cond-cleanup.save");
2358+
CGF.getBuilder().createStore(loc, value, alloca);
2359+
2360+
return saved_type(alloca.emitRawPointer(), true);
23192361
}
23202362

23212363
inline mlir::Value DominatingCIRValue::restore(CIRGenFunction &CGF,

0 commit comments

Comments
 (0)