Skip to content

Commit 1cc4750

Browse files
committed
Merge branch 'master' into logg
merge logg
2 parents 1b7d60f + 6080a13 commit 1cc4750

22 files changed

+374
-307
lines changed

rir/src/compiler/analysis/verifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class TheVerifier {
272272
}
273273
if (auto assume = Assume::Cast(i)) {
274274
if (IsType::Cast(assume->arg(0).val())) {
275-
if (assume->feedbackOrigin.empty()) {
275+
if (!assume->reason.pc()) {
276276
std::cerr << "Error: instruction '";
277277
i->print(std::cerr);
278278
std::cerr << "' typecheck without origin information\n";

rir/src/compiler/backend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ static void lower(Code* code) {
204204
next = it + 1;
205205

206206
} else if (auto expect = Assume::Cast(*it)) {
207-
if (expect->arg(0).val() == True::instance()) {
207+
if (expect->triviallyHolds()) {
208208
next = bb->remove(it);
209209
} else {
210210
auto expectation = expect->assumeTrue;

rir/src/compiler/native/lower_function_llvm.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ class NativeAllocator : public SSAAllocator {
8080
// Ensure we preserve slots for variables with typefeedback to make them
8181
// accessible to the runtime profiler.
8282
// TODO: this needs to be replaced by proper mapping of slots.
83-
if (a != b && (a->typeFeedback().origin || b->typeFeedback().origin))
83+
if (a != b && (a->typeFeedback().feedbackOrigin.pc() ||
84+
b->typeFeedback().feedbackOrigin.pc()))
8485
return true;
8586
return SSAAllocator::interfere(a, b);
8687
}
@@ -1927,14 +1928,15 @@ llvm::Value* LowerFunctionLLVM::fastVeceltOkNative(llvm::Value* v) {
19271928
auto attrs = attr(v);
19281929
auto isNil = builder.CreateICmpEQ(attrs, constant(R_NilValue, t::SEXP));
19291930
auto ok = builder.CreateAnd(builder.CreateNot(isObj(v)), isNil);
1930-
return createSelect2(ok, [&]() { return builder.getTrue(); },
1931-
[&]() {
1932-
auto isMatr1 = builder.CreateICmpEQ(
1933-
tag(attrs), constant(R_DimSymbol, t::SEXP));
1934-
auto isMatr2 = builder.CreateICmpEQ(
1935-
cdr(attrs), constant(R_NilValue, t::SEXP));
1936-
return builder.CreateAnd(isMatr1, isMatr2);
1937-
});
1931+
return createSelect2(
1932+
ok, [&]() { return builder.getTrue(); },
1933+
[&]() {
1934+
auto isMatr1 = builder.CreateICmpEQ(tag(attrs),
1935+
constant(R_DimSymbol, t::SEXP));
1936+
auto isMatr2 =
1937+
builder.CreateICmpEQ(cdr(attrs), constant(R_NilValue, t::SEXP));
1938+
return builder.CreateAnd(isMatr1, isMatr2);
1939+
});
19381940
};
19391941

19401942
llvm::Value* LowerFunctionLLVM::isAltrep(llvm::Value* v) {
@@ -2291,15 +2293,14 @@ void LowerFunctionLLVM::compile() {
22912293
llvm::ConstantInt::get(
22922294
PirJitLLVM::getContext(),
22932295
llvm::APInt(
2294-
64, reinterpret_cast<uint64_t>(rec->reason.srcCode),
2296+
64,
2297+
reinterpret_cast<uint64_t>(rec->reason.srcCode()),
22952298
false)),
22962299
t::voidPtr);
22972300
auto reason = llvm::ConstantStruct::get(
2298-
t::DeoptReason, {
2299-
c(rec->reason.reason, 32),
2300-
srcAddr,
2301-
c(rec->reason.originOffset),
2302-
});
2301+
t::DeoptReason,
2302+
{c(rec->reason.reason, 32),
2303+
c(rec->reason.origin.offset(), 32), srcAddr});
23032304
call(NativeBuiltins::get(NativeBuiltins::Id::recordDeopt),
23042305
{loadSxp(rec->arg<0>().val()), globalConst(reason)});
23052306
break;
@@ -5896,12 +5897,12 @@ void LowerFunctionLLVM::compile() {
58965897
auto i = var.first;
58975898
if (Representation::Of(i) != Representation::Sexp)
58985899
continue;
5899-
if (!i->typeFeedback().origin)
5900+
if (!i->typeFeedback().feedbackOrigin.pc())
59005901
continue;
59015902
if (!var.second.initialized)
59025903
continue;
59035904
if (var.second.stackSlot < PirTypeFeedback::MAX_SLOT_IDX) {
5904-
codes.insert(i->typeFeedback().srcCode);
5905+
codes.insert(i->typeFeedback().feedbackOrigin.srcCode());
59055906
variableMapping.emplace(var.second.stackSlot, i->typeFeedback());
59065907
#ifdef DEBUG_REGISTER_MAP
59075908
assert(!usedSlots.count(var.second.stackSlot));

rir/src/compiler/native/types_llvm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void initializeTypes(LLVMContext& context) {
109109
t::RCNTXT->setBody(fields);
110110

111111
t::DeoptReason = StructType::create(context, "DeoptReason");
112-
fields = {t::i32, t::voidPtr, t::i32};
112+
fields = {t::i32, t::i32, t::voidPtr};
113113
t::DeoptReason->setBody(fields, true);
114114

115115
#define DECLARE(name, ret, ...) \

rir/src/compiler/opt/assumptions.cpp

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,44 @@ struct AAssumption {
2020
}
2121
explicit AAssumption(Assume* a) : yesNo(a->assumeTrue) {
2222
auto cond = a->condition();
23-
if (auto t = IsType::Cast(cond)) {
24-
kind = Typecheck;
25-
c.typecheck = {t->arg(0).val(), t->typeTest};
26-
} else if (auto t = Identical::Cast(cond)) {
27-
kind = Equality;
28-
c.equality = {t->arg(0).val(), t->arg(1).val()};
29-
} else if (auto t = IsEnvStub::Cast(cond)) {
30-
kind = IsEnvStub;
31-
c.env = t->env();
32-
} else {
33-
kind = Other;
34-
c.misc = cond;
23+
switch (a->reason.reason) {
24+
case DeoptReason::Typecheck: {
25+
if (auto t = IsType::Cast(cond)) {
26+
c.typecheck = {t->arg(0).val(), t->typeTest};
27+
kind = Typecheck;
28+
return;
29+
}
30+
break;
3531
}
36-
}
37-
explicit AAssumption(Branch* b, bool yesNo) : yesNo(yesNo) {
38-
auto cond = b->arg(0).val();
39-
if (auto t = IsType::Cast(cond)) {
40-
kind = Typecheck;
41-
c.typecheck = {t->arg(0).val(), t->typeTest};
42-
} else if (auto t = Identical::Cast(cond)) {
43-
kind = Equality;
44-
c.equality = {t->arg(0).val(), t->arg(1).val()};
45-
} else if (auto t = IsEnvStub::Cast(cond)) {
46-
kind = IsEnvStub;
47-
c.env = t->env();
48-
} else {
49-
kind = Other;
50-
c.misc = cond;
32+
case DeoptReason::Calltarget: {
33+
if (auto t = Identical::Cast(cond)) {
34+
c.equality = {t->arg(0).val(), t->arg(1).val()};
35+
kind = Equality;
36+
return;
37+
}
38+
break;
39+
}
40+
case DeoptReason::EnvStubMaterialized: {
41+
if (auto t = IsEnvStub::Cast(cond)) {
42+
c.env = t->env();
43+
kind = IsEnvStub;
44+
return;
45+
}
46+
break;
5147
}
48+
case DeoptReason::DeadBranchReached:
49+
break;
50+
case DeoptReason::DeadCall:
51+
assert(false);
52+
break;
53+
}
54+
55+
// Fallthrough generic case. Assumptions are identified by the concrete
56+
// condition alone.
57+
kind = Other;
58+
c.misc = cond;
5259
}
60+
5361
AAssumption& operator=(const AAssumption& o) {
5462
yesNo = o.yesNo;
5563
kind = o.kind;
@@ -253,14 +261,6 @@ bool OptimizeAssumptions::apply(Compiler&, ClosureVersion* vers, Code* code,
253261
return false;
254262
};
255263

256-
if (auto br = Branch::Cast(instr)) {
257-
if (assumptionsIncludes(AAssumption(br, true))) {
258-
br->arg(0).val() = True::instance();
259-
} else if (assumptionsIncludes(AAssumption(br, false))) {
260-
br->arg(0).val() = False::instance();
261-
}
262-
}
263-
264264
if (auto assume = Assume::Cast(instr)) {
265265
if (assumptionsIncludes(AAssumption(assume))) {
266266
anyChange = true;
@@ -327,11 +327,9 @@ bool OptimizeAssumptions::apply(Compiler&, ClosureVersion* vers, Code* code,
327327
if (h != hoistAssume.end()) {
328328
auto g = h->second;
329329
ip++;
330-
auto assume = new Assume(std::get<0>(g), std::get<1>(g));
331-
assume->feedbackOrigin.insert(
332-
assume->feedbackOrigin.end(),
333-
std::get<2>(g)->feedbackOrigin.begin(),
334-
std::get<2>(g)->feedbackOrigin.end());
330+
auto assume = new Assume(std::get<Instruction*>(g),
331+
std::get<Checkpoint*>(g),
332+
std::get<Assume*>(g)->reason);
335333
ip = bb->insert(ip, assume);
336334
anyChange = true;
337335
}

rir/src/compiler/opt/constantfold.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ bool Constantfold::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
302302
auto next = ip + 1;
303303

304304
auto killUnreachable = [&]() {
305-
if (ip == bb->end() || Unreachable::Cast(*(ip + 1)))
305+
if (ip == bb->end() || Unreachable::Cast(bb->last()))
306306
return;
307307
ip = bb->insert(ip + 1, new Unreachable()) + 1;
308308
while (ip != bb->end())

rir/src/compiler/opt/eager_calls.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,22 @@ bool EagerCalls::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
1818
LogStream& log) const {
1919
AvailableCheckpoints checkpoint(cls, code, log);
2020

21+
struct Speculation {
22+
SEXP builtin;
23+
Checkpoint* cp;
24+
FeedbackOrigin origin;
25+
};
26+
2127
auto replaceLdFunBuiltinWithDeopt = [&](BB* bb, BB::Instrs::iterator ip,
22-
Checkpoint* cp, SEXP builtin,
28+
const Speculation& speculation,
2329
LdFun* ldfun) {
2430
assert(LdFun::Cast(*ip));
25-
assert(cp);
31+
assert(speculation.cp);
2632

2733
// skip ldfun
2834
++ip;
2935

30-
auto expected = new LdConst(builtin);
36+
auto expected = new LdConst(speculation.builtin);
3137
ip = bb->insert(ip, expected);
3238
++ip;
3339
Instruction* given = ldfun;
@@ -54,7 +60,9 @@ bool EagerCalls::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
5460
ip = bb->insert(ip, test);
5561
++ip;
5662

57-
auto assume = new Assume(test, cp);
63+
auto assume = new Assume(
64+
test, speculation.cp,
65+
DeoptReason(speculation.origin, DeoptReason::Calltarget));
5866
ip = bb->insert(ip, assume);
5967
++ip;
6068

@@ -105,7 +113,8 @@ bool EagerCalls::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
105113
};
106114

107115
// Search for calls that likely point to a builtin.
108-
std::unordered_map<LdFun*, std::pair<SEXP, Checkpoint*>> needsGuard;
116+
std::unordered_map<LdFun*, Speculation> needsGuard;
117+
109118
Visitor::run(code->entry, [&](BB* bb) {
110119
auto ip = bb->begin();
111120
while (ip != bb->end()) {
@@ -144,8 +153,8 @@ bool EagerCalls::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
144153
Effect::DependsOnAssume));
145154
}
146155
} else if (auto ldfun = LdFun::Cast(call->cls())) {
147-
if (ldfun->hint && !ldfun->hintIsInnerFunction) {
148-
auto kind = TYPEOF(ldfun->hint);
156+
if (ldfun->hint() && !ldfun->hintIsInnerFunction) {
157+
auto kind = TYPEOF(ldfun->hint());
149158
// We also speculate on calls to CLOSXPs, these will
150159
// be picked up by MatchArgs opt pass and turned
151160
// into a static call. TODO, for inner functions we
@@ -157,9 +166,10 @@ bool EagerCalls::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
157166
if (auto cp = checkpoint.at(ldfun)) {
158167
if (kind == BUILTINSXP) {
159168
ip = replaceCallWithCallBuiltin(
160-
bb, ip, call, ldfun->hint, true);
169+
bb, ip, call, ldfun->hint(), true);
161170
}
162-
needsGuard[ldfun] = {ldfun->hint, cp};
171+
needsGuard[ldfun] = {ldfun->hint(), cp,
172+
ldfun->hintOrigin()};
163173
}
164174
}
165175
} else {
@@ -218,8 +228,7 @@ bool EagerCalls::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
218228
if (auto ldfun = LdFun::Cast(*ip)) {
219229
auto r = needsGuard.find(ldfun);
220230
if (r != needsGuard.end()) {
221-
ip = replaceLdFunBuiltinWithDeopt(bb, ip, r->second.second,
222-
r->second.first, ldfun);
231+
ip = replaceLdFunBuiltinWithDeopt(bb, ip, r->second, ldfun);
223232
needsGuard.erase(r);
224233
continue;
225234
}

rir/src/compiler/opt/elide_env_spec.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,9 @@ bool ElideEnvSpec::apply(Compiler&, ClosureVersion* cls, Code* code,
8787
arg, seen, suggested, required,
8888
[&](TypeTest::Info info) {
8989
BBTransform::insertAssume(
90-
info.test, cp, bb, ip, info.expectation,
91-
info.srcCode, info.origin);
90+
info.test, info.expectation, cp,
91+
info.feedbackOrigin, DeoptReason::Typecheck,
92+
bb, ip);
9293

9394
if (argi) {
9495
auto cast = new CastType(
@@ -129,6 +130,7 @@ bool ElideEnvSpec::apply(Compiler&, ClosureVersion* cls, Code* code,
129130
!arg->type.maybeMissing()) {
130131
force->replaceUsesWith(arg);
131132
next = bb->remove(ip);
133+
anyChange = true;
132134
}
133135
}
134136
}
@@ -281,8 +283,10 @@ bool ElideEnvSpec::apply(Compiler&, ClosureVersion* cls, Code* code,
281283
if (!bannedEnvs.count(env)) {
282284
auto condition = new IsEnvStub(env);
283285
BBTransform::insertAssume(
284-
condition, cp, true,
285-
env->typeFeedback().srcCode, nullptr);
286+
condition, true, cp,
287+
env->typeFeedback().feedbackOrigin,
288+
DeoptReason::EnvStubMaterialized);
289+
anyChange = true;
286290
assert(cp->bb()->trueBranch() != bb);
287291
}
288292
}
@@ -301,6 +305,7 @@ bool ElideEnvSpec::apply(Compiler&, ClosureVersion* cls, Code* code,
301305
for (auto n : additionalEntries[env]) {
302306
env->varName.push_back(n);
303307
env->pushArg(UnboundValue::instance(), PirType::any());
308+
anyChange = true;
304309
}
305310
// After eliding an env we must ensure to add a
306311
// materialization before every usage in deopt branches
@@ -331,17 +336,20 @@ bool ElideEnvSpec::apply(Compiler&, ClosureVersion* cls, Code* code,
331336
!i->effects.contains(Effect::DependsOnAssume) &&
332337
MkEnv::Cast(i->env()) && MkEnv::Cast(i->env())->stub) {
333338
i->effects.set(Effect::DependsOnAssume);
339+
anyChange = true;
334340
}
335341
if (auto is = IsEnvStub::Cast(i)) {
336342
if (!materializableStubs.count(i->env())) {
337343
is->replaceUsesWith(True::instance());
338344
is->effects.reset();
345+
anyChange = true;
339346
}
340347
}
341348
if (auto mk = MkArg::Cast(i)) {
342349
if (materializableStubs.count(mk->env())) {
343350
if (auto e = mk->prom()->env()) {
344351
e->stub = true;
352+
anyChange = true;
345353
}
346354
}
347355
}

rir/src/compiler/opt/match_call_args.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ bool MatchCallArgs::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
203203
false,
204204
[&](ClosureVersion* fun) { target = fun; },
205205
[]() {}, {});
206-
} else if (auto cnst = LdConst::Cast(calli->tryGetClsArg())) {
206+
} else if (auto cnst =
207+
LdConst::Cast(calli->tryGetClsArg())) {
207208
if (auto dt = DispatchTable::check(BODY(cnst->c()))) {
208209
if (dt->baseline()->body()->codeSize <
209210
Parameter::RECOMPILE_THRESHOLD)
@@ -222,14 +223,14 @@ bool MatchCallArgs::apply(Compiler& cmp, ClosureVersion* cls, Code* code,
222223
auto srcRef = mk->srcRef;
223224
if (dt->baseline()->body()->codeSize <
224225
Parameter::RECOMPILE_THRESHOLD)
225-
cmp.compileFunction(dt, "unknown--fromMkFunCls",
226-
formals, srcRef, asmpt,
227-
[&](ClosureVersion* fun) {
228-
mk->setCls(
229-
fun->owner());
230-
target = fun;
231-
},
232-
[]() {}, {});
226+
cmp.compileFunction(
227+
dt, "unknown--fromMkFunCls", formals,
228+
srcRef, asmpt,
229+
[&](ClosureVersion* fun) {
230+
mk->setCls(fun->owner());
231+
target = fun;
232+
},
233+
[]() {}, {});
233234
}
234235
}
235236
}

rir/src/compiler/opt/type_speculation.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ bool TypeSpeculation::apply(Compiler&, ClosureVersion* cls, Code* code,
130130
auto cp = sp.second.first;
131131
TypeTest::Info& info = sp.second.second;
132132

133-
BBTransform::insertAssume(info.test, cp, bb, ip, info.expectation,
134-
info.srcCode, info.origin);
133+
BBTransform::insertAssume(info.test, info.expectation, cp,
134+
info.feedbackOrigin,
135+
DeoptReason::Typecheck, bb, ip);
135136

136137
auto cast = new CastType(i, CastType::Downcast, PirType::any(),
137138
info.result);

0 commit comments

Comments
 (0)