From a6f30bf84f4d3ea0dd4be13016a996ab5c684261 Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Fri, 1 Mar 2024 18:11:35 +0000 Subject: [PATCH 01/11] try --- rir/src/compiler/pir/instruction.cpp | 12 ++++++++++++ rir/src/compiler/pir/type.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index e18e28c05..b0e6ed35b 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -877,6 +877,18 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { inferred = PirType(RType::vec).orAttribsOrObj(); } + if ("dim" == name) { + if (!getType(callArg(0).val()) + .maybeObj()) { // TODO: is it necessary to check this? + inferred = (PirType(RType::integer) | RType::nil) + .notMissing() + .orNotFastVecelt(); + + // if (getType(callArg(0).val()).isSimpleScalar()) + // inferred = inferred.simpleScalar(); + } + } + if (inferred != PirType::bottom()) return inferred & type; diff --git a/rir/src/compiler/pir/type.h b/rir/src/compiler/pir/type.h index 5202344ff..9c55260a2 100644 --- a/rir/src/compiler/pir/type.h +++ b/rir/src/compiler/pir/type.h @@ -641,7 +641,7 @@ struct PirType { // NULL return RType::nil; } - if (isA((num() | RType::str | RType::list | RType::code) + if (isA((num() | RType::str | RType::list | RType::code | RType::nil) .orAttribsOrObj())) { // If the index is out of bounds, NA is returned (even if both args // are non-NA) so we must add orNAOrNaN() From 1a666ee195c4713af83c5ed620e9b4f72185e31b Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Thu, 7 Mar 2024 12:48:52 +0000 Subject: [PATCH 02/11] more --- rir/src/compiler/pir/instruction.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index b0e6ed35b..897811797 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -1,4 +1,6 @@ #include "instruction.h" +#include "compiler/pir/singleton_values.h" +#include "compiler/pir/type.h" #include "pir_impl.h" #include "../analysis/query.h" @@ -881,11 +883,18 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { if (!getType(callArg(0).val()) .maybeObj()) { // TODO: is it necessary to check this? inferred = (PirType(RType::integer) | RType::nil) + .notNAOrNaN() .notMissing() .orNotFastVecelt(); - // if (getType(callArg(0).val()).isSimpleScalar()) - // inferred = inferred.simpleScalar(); + if (getType(callArg(0).val()).isSimpleScalar()) { + inferred = inferred.simpleScalar(); + std::cerr << "\n" + << "current: " << getType(callArg(0).val()) << "\n"; + std::cerr << "\n" + << "inferred: " << inferred << "\n"; + assert(false); + } } } From 8fe5e30adb700a06ef25a552e2a5a7bb6866f26d Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Thu, 7 Mar 2024 16:58:15 +0000 Subject: [PATCH 03/11] comm --- rir/src/compiler/pir/instruction.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index 897811797..7483d357f 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -887,6 +887,13 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { .notMissing() .orNotFastVecelt(); + std::cerr << "\n ASSERTION1: \n" + << "current argment: " << getType(callArg(0).val()) + << "\n"; + std::cerr << "\n" + << "inferred: " << inferred << "\n"; + + // assert(false); if (getType(callArg(0).val()).isSimpleScalar()) { inferred = inferred.simpleScalar(); std::cerr << "\n" From 585c9538a4bd523c14d088e20093c01bc89b0d61 Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Fri, 8 Mar 2024 10:12:22 +0000 Subject: [PATCH 04/11] 'dim' when no attribs return null --- rir/src/api.cpp | 35 +++++++++++++++++++++++++++- rir/src/api.h | 2 +- rir/src/compiler/pir/instruction.cpp | 17 ++------------ 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/rir/src/api.cpp b/rir/src/api.cpp index 22570da6d..284d48118 100644 --- a/rir/src/api.cpp +++ b/rir/src/api.cpp @@ -601,7 +601,40 @@ REXPORT SEXP rirCreateSimpleIntContext() { return res; } -REXPORT SEXP playground() { +REXPORT SEXP playground(SEXP what) { + + Context baseContext = pir::Compiler::defaultContext; + baseContext.add(Assumption::StaticallyArgmatched); + baseContext.add(Assumption::NoExplicitlyMissingArgs); + baseContext.add(Assumption::CorrectOrderOfArguments); + baseContext.add(Assumption::NotTooManyArguments); + baseContext.numMissing(0); + + pir::DebugOptions opts = pir::DebugOptions::DefaultDebugOptions; + + // C1 (EAGER) + Context c1 = baseContext; + c1.setEager(0); + std::cerr << "Context: " << c1 << "\n"; + pirCompile(what, c1, "nrow", opts); + + // C2 (EAGER + NONOBJ) + Context c2 = c1; + c2.setNotObj(0); + std::cerr << "Context: " << c2 << "\n"; + pirCompile(what, c2, "nrow", opts); + + // C3 (EAGER + NONREFL) + Context c3 = c1; + c3.setNonRefl(0); + std::cerr << "Context: " << c3 << "\n"; + pirCompile(what, c3, "nrow", opts); + + // // C3 (EAGER + NONOBJ) + // Context c2 = c1; + // c2.setNotObj(0); + // std::cerr << "Context: " << c2 << "\n"; + // pirCompile(what, c2, "nrow", opts); return R_NilValue; } diff --git a/rir/src/api.h b/rir/src/api.h index 2ef31ee4f..226d9ef89 100644 --- a/rir/src/api.h +++ b/rir/src/api.h @@ -31,6 +31,6 @@ REXPORT SEXP rirCreateSimpleIntContext(); // this method is just to have an easy way to play around with the code and get // feedback by calling .Call('playground') -REXPORT SEXP playground(); +REXPORT SEXP playground(SEXP what); #endif // API_H_ diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index 7483d357f..6b15d1688 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -886,21 +886,8 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { .notNAOrNaN() .notMissing() .orNotFastVecelt(); - - std::cerr << "\n ASSERTION1: \n" - << "current argment: " << getType(callArg(0).val()) - << "\n"; - std::cerr << "\n" - << "inferred: " << inferred << "\n"; - - // assert(false); - if (getType(callArg(0).val()).isSimpleScalar()) { - inferred = inferred.simpleScalar(); - std::cerr << "\n" - << "current: " << getType(callArg(0).val()) << "\n"; - std::cerr << "\n" - << "inferred: " << inferred << "\n"; - assert(false); + if (!getType(callArg(0).val()).maybeHasAttrs()) { + inferred = PirType(RType::nil); } } } From 3232d4e6a89614f7ba1374c99313696a528dd0da Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Mon, 11 Mar 2024 14:14:51 +0000 Subject: [PATCH 05/11] isInstance exact --- rir/src/compiler/native/builtins.cpp | 2 +- rir/src/compiler/pir/instruction.cpp | 4 ++-- rir/src/compiler/pir/type.cpp | 21 +++++++++++++-------- rir/src/compiler/pir/type.h | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/rir/src/compiler/native/builtins.cpp b/rir/src/compiler/native/builtins.cpp index bd3f627c9..74513b669 100644 --- a/rir/src/compiler/native/builtins.cpp +++ b/rir/src/compiler/native/builtins.cpp @@ -2247,7 +2247,7 @@ bool deoptChaosTriggerImpl(bool deoptTrue) { void checkTypeImpl(SEXP val, uint64_t type, const char* msg) { assert(pir::Parameter::RIR_CHECK_PIR_TYPES); pir::PirType typ(type); - if (!typ.isInstance(val)) { + if (!typ.isInstance(val, true)) { std::cerr << "type assert failed\n"; std::cerr << "got " << pir::PirType(val) << " but expected a " << typ << ":\n"; diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index 6b15d1688..b2be1a517 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -883,9 +883,9 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { if (!getType(callArg(0).val()) .maybeObj()) { // TODO: is it necessary to check this? inferred = (PirType(RType::integer) | RType::nil) - .notNAOrNaN() .notMissing() - .orNotFastVecelt(); + .orAttribsOrObj(); + if (!getType(callArg(0).val()).maybeHasAttrs()) { inferred = PirType(RType::nil); } diff --git a/rir/src/compiler/pir/type.cpp b/rir/src/compiler/pir/type.cpp index a5a8b19ee..8d6c0aea3 100644 --- a/rir/src/compiler/pir/type.cpp +++ b/rir/src/compiler/pir/type.cpp @@ -95,14 +95,17 @@ void PirType::merge(SEXPTYPE sexptype) { // contain NaN for the benefit, so we simple assume they do static const R_xlen_t MAX_SIZE_OF_VECTOR_FOR_NAN_CHECK = 1; -static bool maybeContainsNAOrNaN(SEXP vector) { +static bool maybeContainsNAOrNaN(SEXP vector, bool exact) { if (TYPEOF(vector) == CHARSXP) { return vector == NA_STRING; } else if (TYPEOF(vector) == INTSXP || TYPEOF(vector) == REALSXP || TYPEOF(vector) == LGLSXP || TYPEOF(vector) == CPLXSXP || TYPEOF(vector) == STRSXP) { - if (XLENGTH(vector) > MAX_SIZE_OF_VECTOR_FOR_NAN_CHECK) { - return true; + + if (!exact) { + if (XLENGTH(vector) > MAX_SIZE_OF_VECTOR_FOR_NAN_CHECK) { + return true; + } } for (int i = 0; i < XLENGTH(vector); i++) { switch (TYPEOF(vector)) { @@ -137,7 +140,7 @@ static bool maybeContainsNAOrNaN(SEXP vector) { } } -PirType::PirType(SEXP e) : flags_(topRTypeFlags()), t_(RTypeSet()) { +PirType::PirType(SEXP e, bool exact) : flags_(topRTypeFlags()), t_(RTypeSet()) { if (e == R_MissingArg) { *this = theMissingValue(); @@ -179,7 +182,7 @@ PirType::PirType(SEXP e) : flags_(topRTypeFlags()), t_(RTypeSet()) { if (t != LISTSXP && t != EXTERNALSXP && t != BCODESXP && t != LANGSXP) if (Rf_xlength(e) == 1) flags_.reset(TypeFlags::maybeNotScalar); - if (!maybeContainsNAOrNaN(e)) + if (!maybeContainsNAOrNaN(e, exact)) flags_.reset(TypeFlags::maybeNAOrNaN); } @@ -210,14 +213,14 @@ void PirType::merge(const ObservedValues& other) { *this = orSexpTypes(any()); } -bool PirType::isInstance(SEXP val) const { +bool PirType::isInstance(SEXP val, bool exact) const { if (isRType()) { if (TYPEOF(val) == PROMSXP) { assert(!Rf_isObject(val)); if (maybePromiseWrapped() && !maybeLazy()) { auto v = PRVALUE(val); return v != R_UnboundValue && - notMissing().forced().isInstance(v); + notMissing().forced().isInstance(v, exact); } return maybe(RType::prom) || (maybeLazy() && maybePromiseWrapped()); } @@ -229,7 +232,9 @@ bool PirType::isInstance(SEXP val) const { return IS_SIMPLE_SCALAR(val, LGLSXP) && LOGICAL(val)[0] != NA_LOGICAL; } - return PirType(val).isA(*this); + + return PirType(val, exact).isA(*this); + ; } else { std::cerr << "can't check val is instance of " << *this << ", value:\n"; Rf_PrintValue(val); diff --git a/rir/src/compiler/pir/type.h b/rir/src/compiler/pir/type.h index 9c55260a2..e23ac18dc 100644 --- a/rir/src/compiler/pir/type.h +++ b/rir/src/compiler/pir/type.h @@ -179,7 +179,7 @@ struct PirType { // cppcheck-suppress noExplicitConstructor constexpr PirType(const NativeTypeSet& t) : t_(t) {} - explicit PirType(SEXP); + explicit PirType(SEXP, bool exact = false); constexpr PirType(const PirType& other) : flags_(other.flags_), t_(other.t_) {} @@ -750,7 +750,7 @@ struct PirType { } // Is val an instance of this type? - bool isInstance(SEXP val) const; + bool isInstance(SEXP val, bool exact = false) const; void print(std::ostream& out = std::cout) const; From 32419b870b6f13fcc4301686e94a595e4cf13a36 Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Tue, 12 Mar 2024 15:57:17 +0000 Subject: [PATCH 06/11] a --- rir/src/compiler/pir/value.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rir/src/compiler/pir/value.cpp b/rir/src/compiler/pir/value.cpp index bd9380e56..c7e3793d7 100644 --- a/rir/src/compiler/pir/value.cpp +++ b/rir/src/compiler/pir/value.cpp @@ -9,6 +9,14 @@ namespace rir { namespace pir { +static void checkEagerImpliesNoRef(Context& assumptions) { + for (int i = 0; i <= 5; i++) { + if (assumptions.isEager(i)) { + assert(assumptions.isNonRefl(i) && "non refl"); + } + } +} + void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { // this is for function arguments auto arg = this; @@ -22,6 +30,7 @@ void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { assumptions.setEager(i); arg = mk->eagerArg(); } else { + checkEagerImpliesNoRef(assumptions); return; } } else { @@ -31,6 +40,7 @@ void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { if (arg == MissingArg::instance()) { assumptions.remove(Assumption::NoExplicitlyMissingArgs); + checkEagerImpliesNoRef(assumptions); return; } @@ -56,6 +66,8 @@ void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { arg = arg->cFollowCastsAndForce(); if (!MkArg::Cast(arg)) check(arg); + + checkEagerImpliesNoRef(assumptions); } void Value::checkReplace(Value* replace) const { From 59e0db1e7e0eecdc9fd1aba4e35d48ac376cc3a1 Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Wed, 13 Mar 2024 09:42:48 +0000 Subject: [PATCH 07/11] try not nil --- rir/src/compiler/pir/instruction.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index b2be1a517..40d04f20e 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -886,9 +886,9 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { .notMissing() .orAttribsOrObj(); - if (!getType(callArg(0).val()).maybeHasAttrs()) { - inferred = PirType(RType::nil); - } + // if (!getType(callArg(0).val()).maybeHasAttrs()) { + // inferred = PirType(RType::nil); + // } } } From b9d64aadc7b73f5adc75171fd5edf1ceeefd3468 Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Wed, 13 Mar 2024 10:03:43 +0000 Subject: [PATCH 08/11] restore --- rir/src/api.cpp | 38 +------------------------------------- rir/src/api.h | 2 +- 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/rir/src/api.cpp b/rir/src/api.cpp index 284d48118..487dce219 100644 --- a/rir/src/api.cpp +++ b/rir/src/api.cpp @@ -601,43 +601,7 @@ REXPORT SEXP rirCreateSimpleIntContext() { return res; } -REXPORT SEXP playground(SEXP what) { - - Context baseContext = pir::Compiler::defaultContext; - baseContext.add(Assumption::StaticallyArgmatched); - baseContext.add(Assumption::NoExplicitlyMissingArgs); - baseContext.add(Assumption::CorrectOrderOfArguments); - baseContext.add(Assumption::NotTooManyArguments); - baseContext.numMissing(0); - - pir::DebugOptions opts = pir::DebugOptions::DefaultDebugOptions; - - // C1 (EAGER) - Context c1 = baseContext; - c1.setEager(0); - std::cerr << "Context: " << c1 << "\n"; - pirCompile(what, c1, "nrow", opts); - - // C2 (EAGER + NONOBJ) - Context c2 = c1; - c2.setNotObj(0); - std::cerr << "Context: " << c2 << "\n"; - pirCompile(what, c2, "nrow", opts); - - // C3 (EAGER + NONREFL) - Context c3 = c1; - c3.setNonRefl(0); - std::cerr << "Context: " << c3 << "\n"; - pirCompile(what, c3, "nrow", opts); - - // // C3 (EAGER + NONOBJ) - // Context c2 = c1; - // c2.setNotObj(0); - // std::cerr << "Context: " << c2 << "\n"; - // pirCompile(what, c2, "nrow", opts); - - return R_NilValue; -} +REXPORT SEXP playground() { return R_NilValue; } bool startup() { initializeRuntime(); diff --git a/rir/src/api.h b/rir/src/api.h index 226d9ef89..2ef31ee4f 100644 --- a/rir/src/api.h +++ b/rir/src/api.h @@ -31,6 +31,6 @@ REXPORT SEXP rirCreateSimpleIntContext(); // this method is just to have an easy way to play around with the code and get // feedback by calling .Call('playground') -REXPORT SEXP playground(SEXP what); +REXPORT SEXP playground(); #endif // API_H_ From b5d19469f7605dd0c0f5487f9c5316731e9b7d2d Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Wed, 13 Mar 2024 10:08:48 +0000 Subject: [PATCH 09/11] cleanup --- rir/src/compiler/pir/instruction.cpp | 2 -- rir/src/compiler/pir/value.cpp | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index 40d04f20e..e0c2be44b 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -1,6 +1,4 @@ #include "instruction.h" -#include "compiler/pir/singleton_values.h" -#include "compiler/pir/type.h" #include "pir_impl.h" #include "../analysis/query.h" diff --git a/rir/src/compiler/pir/value.cpp b/rir/src/compiler/pir/value.cpp index c7e3793d7..19513c97e 100644 --- a/rir/src/compiler/pir/value.cpp +++ b/rir/src/compiler/pir/value.cpp @@ -9,14 +9,6 @@ namespace rir { namespace pir { -static void checkEagerImpliesNoRef(Context& assumptions) { - for (int i = 0; i <= 5; i++) { - if (assumptions.isEager(i)) { - assert(assumptions.isNonRefl(i) && "non refl"); - } - } -} - void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { // this is for function arguments auto arg = this; @@ -30,7 +22,6 @@ void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { assumptions.setEager(i); arg = mk->eagerArg(); } else { - checkEagerImpliesNoRef(assumptions); return; } } else { @@ -40,7 +31,6 @@ void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { if (arg == MissingArg::instance()) { assumptions.remove(Assumption::NoExplicitlyMissingArgs); - checkEagerImpliesNoRef(assumptions); return; } @@ -67,7 +57,6 @@ void Value::callArgTypeToContext(Context& assumptions, unsigned i) const { if (!MkArg::Cast(arg)) check(arg); - checkEagerImpliesNoRef(assumptions); } void Value::checkReplace(Value* replace) const { From d792f044fe0da5389da1290fd8ebe841d597377c Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Fri, 15 Mar 2024 16:05:19 +0000 Subject: [PATCH 10/11] undo refine type for dim --- rir/src/compiler/pir/instruction.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rir/src/compiler/pir/instruction.cpp b/rir/src/compiler/pir/instruction.cpp index e0c2be44b..42947010d 100644 --- a/rir/src/compiler/pir/instruction.cpp +++ b/rir/src/compiler/pir/instruction.cpp @@ -880,9 +880,9 @@ PirType CallSafeBuiltin::inferType(const Instruction::GetType& getType) const { if ("dim" == name) { if (!getType(callArg(0).val()) .maybeObj()) { // TODO: is it necessary to check this? - inferred = (PirType(RType::integer) | RType::nil) - .notMissing() - .orAttribsOrObj(); + // inferred = (PirType(RType::integer) | RType::nil) + // .notMissing() + // .orAttribsOrObj(); // if (!getType(callArg(0).val()).maybeHasAttrs()) { // inferred = PirType(RType::nil); From b8c4e8864c18b4e45856de36f369f77683706e3c Mon Sep 17 00:00:00 2001 From: Sebastian Krynski Date: Mon, 18 Mar 2024 09:58:10 +0000 Subject: [PATCH 11/11] undo RType::nil --- rir/src/compiler/pir/type.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rir/src/compiler/pir/type.h b/rir/src/compiler/pir/type.h index e23ac18dc..26ffe1888 100644 --- a/rir/src/compiler/pir/type.h +++ b/rir/src/compiler/pir/type.h @@ -641,7 +641,8 @@ struct PirType { // NULL return RType::nil; } - if (isA((num() | RType::str | RType::list | RType::code | RType::nil) + if (isA((num() | RType::str | RType::list | + RType::code /* | RType::nil */) .orAttribsOrObj())) { // If the index is out of bounds, NA is returned (even if both args // are non-NA) so we must add orNAOrNaN()