Skip to content

Instantly share code, notes, and snippets.

View zoecarver's full-sized avatar

Zoe Carver zoecarver

View GitHub Profile
// C++
template<class T>
struct MyVector {
using element_type = T;
using iterator_type = T*; // or some trait.
element_type operator[](unsigned i) { ... }
iterator_type begin() { ... }
iterator_type end() { ... }
};

ParserSIL

Problem Statement

The SIL parser is one 7000 line file. It attempts to do three things: read SIL text, check and verify the input, and transform the input into SIL instructions/functions/etc. There are, at least, five overarching problems with the current implementation:

  1. The current implementation is old, complicated, and monolithic.
  2. The parser is a standalone library (for no good reason) which complicates the build system.
  3. It is hard to have "drop-in" tooling with this implementation.
  4. The current implementation has no interoperability with the serializer.
  5. The current implementation tries to do everything in one place: read, check and parse.

Solution

//
// main.cpp
// vector
//
// Created by Zoe Carver on 4/7/20.
//
#include <iostream>
#include <fstream>
#include <vector>
sil [transparent] @closure : $@convention(thin) (Builtin.Int32) -> Builtin.Int32
sil hidden [ossa] @test : $@convention(thin) (Builtin.Int1) -> () {
// %0 // user: %6
bb0(%0 : $Builtin.Int1):
%1 = alloc_box ${ var @callee_guaranteed (Builtin.Int32) -> Builtin.Int32 }, var, name "c" // users: %19, %2
%2 = project_box %1 : ${ var @callee_guaranteed (Builtin.Int32) -> Builtin.Int32 }, 0 // users: %14, %7, %5
// function_ref closure #1 in test(x:)
%3 = function_ref @closure : $@convention(thin) (Builtin.Int32) -> Builtin.Int32 // user: %4
%4 = thin_to_thick_function %3 : $@convention(thin) (Builtin.Int32) -> Builtin.Int32 to $@callee_guaranteed (Builtin.Int32) -> Builtin.Int32 // user: %5
SIL verification failed: Operand is of an ArchetypeType that does not exist in the Caller's generic param list.: isArchetypeValidInFunction(A, F)
Verifying instruction:
%0 = argument of bb0 : $τ_1_0 // user: %1
-> %1 = init_existential_ref %0 : $τ_1_0 : $τ_1_0, $ClassA<T> & ProtocolA // users: %3, %2
debug_value %1 : $ClassA<T> & ProtocolA, let, name "x", argno 1 // id: %2
%3 = open_existential_ref %1 : $ClassA<T> & ProtocolA to $@opened("1A205440-FF82-11E9-A915-ACBC329C418B") ClassA<τ_0_0> & ProtocolA // users: %7, %6, %5, %4
In function:
// specialized shouldOptimize1<A>(_:)
sil shared @$s3run15shouldOptimize1ySiAA9ProtocolA_AA6ClassACyxGXclFTf4e_n : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : ClassA<τ_0_0>, τ_1_0 : ProtocolA> (@guaranteed τ_1_0) -> Int {
// %0 // user: %1
struct I {
virtual ~I() = default;
};
struct A : public I { int value = 1; };
struct B : public I { int value = 2; };
struct C : public I { int value = 3; };
template <template <int...> class _Tp, class>
struct instance_of : std::false_type { };
case Builtin::BI__builtin_llroundf: {
APFloat FPVal(0.0);
APSInt IVal;
bool isExact = true;
if(!EvaluateFloat(E->getArg(0), FPVal, Info)) return false;
// I have also tried with several other rm values.
FPVal.convertToInteger(IVal, APFloat::rmNearestTiesToEven, &isExact);
return Success(IVal.getExtValue(), E);
}
@zoecarver
zoecarver / main.cpp
Last active June 8, 2019 00:02
Uses allocator construction issue with perfect forwarding
using namespace std;
template<class T1, class T2>
void join(T1&& t1, T2&& t2)
{
static_assert(is_same<decltype(get<0>(t1)), int&&>::value); // fails
}
template<class T1, class T2>
auto foward_pair(pair<T1, T2>&& p)
@zoecarver
zoecarver / main.cpp
Last active June 7, 2019 23:57
Uses allocator construction forward_as_tuple issue
using namespace std;
template<class A, class... Args>
auto add_and_forward(A a, Args&&... args)
{
return forward_as_tuple(a, forward<Args>(args)...); // <--- here is our issue
}
template<class A, class T1, class T2>
auto join(A a, T1 t1, T2 t2)
@zoecarver
zoecarver / test.cpp
Created May 13, 2019 23:47
Speed comparison of unordered_multiset
#include<chrono>
#include<unordered_set>
#include<iostream>
#include<cassert>
using namespace std;
using namespace std::chrono;
template <class _Value, class _Hash, class _Pred, class _Alloc>
bool