Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evacuate set and map iterators during garbage collection #441

Merged
merged 12 commits into from
Oct 20, 2021
Merged
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ set(STRINGBUFFER_LAYOUT 6)
set(BOOL_LAYOUT 7)
set(SYMBOL_LAYOUT 8)
set(VARIABLE_LAYOUT 9)
set(SETITER_LAYOUT 11)
set(MAPITER_LAYOUT 12)

get_filename_component(INSTALL_DIR_ABS_PATH "${CMAKE_INSTALL_PREFIX}"
REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
Expand Down
2 changes: 2 additions & 0 deletions config/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#define BOOL_LAYOUT @BOOL_LAYOUT@
#define SYMBOL_LAYOUT @SYMBOL_LAYOUT@
#define VARIABLE_LAYOUT @VARIABLE_LAYOUT@
#define SETITER_LAYOUT @SETITER_LAYOUT@
#define MAPITER_LAYOUT @MAPITER_LAYOUT@

#define STRINGIFY(x) #x
#define TOSTRING(X) STRINGIFY(X)
Expand Down
2 changes: 1 addition & 1 deletion deps/immer
4 changes: 3 additions & 1 deletion include/kllvm/ast/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ enum class SortCategory {
Bool,
Symbol,
Variable,
MInt
MInt,
SetIterator,
MapIterator,
};

// represents the syntactic category of an LLVM backend term at runtime
Expand Down
10 changes: 2 additions & 8 deletions include/kllvm/codegen/Decision.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ class Decision {
llvm::LLVMContext &Ctx;
ValueType Cat;
llvm::PHINode *FailSubject, *FailPattern, *FailSort;
llvm::Value *ResultBuffer, *ResultCount, *ResultCapacity;

std::map<var_type, llvm::AllocaInst *> symbols;

Expand All @@ -383,9 +382,7 @@ class Decision {
llvm::BasicBlock *FailureBlock, llvm::IndirectBrInst *FailJump,
llvm::AllocaInst *ChoiceBuffer, llvm::AllocaInst *ChoiceDepth,
llvm::Module *Module, ValueType Cat, llvm::PHINode *FailSubject,
llvm::PHINode *FailPattern, llvm::PHINode *FailSort,
llvm::Value *ResultBuffer, llvm::Value *ResultCount,
llvm::Value *ResultCapacity)
llvm::PHINode *FailPattern, llvm::PHINode *FailSort)
: Definition(Definition)
, CurrentBlock(EntryBlock)
, FailureBlock(FailureBlock)
Expand All @@ -398,10 +395,7 @@ class Decision {
, Cat(Cat)
, FailSubject(FailSubject)
, FailPattern(FailPattern)
, FailSort(FailSort)
, ResultBuffer(ResultBuffer)
, ResultCount(ResultCount)
, ResultCapacity(ResultCapacity) { }
, FailSort(FailSort) { }

/* adds code to the specified basic block to take a single step based on
the specified decision tree and return the result of taking that step. */
Expand Down
2 changes: 2 additions & 0 deletions include/runtime/collect.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ void migrate_once(block **);
void migrate_list(void *l);
void migrate_map(void *m);
void migrate_set(void *s);
void evacuate_setiter(void *s);
void evacuate_mapiter(void *s);
void migrate_collection_node(void **nodePtr);
void setKoreMemoryFunctionsForGMP(void);
void koreCollect(void);
Expand Down
2 changes: 2 additions & 0 deletions lib/ast/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ std::string KORESymbol::layoutString(KOREDefinition *definition) const {
result.append("_" + std::to_string(cat.bits) + "_");
case SortCategory::Symbol: result.push_back('0'); break;
case SortCategory::Uncomputed: abort();
case SortCategory::SetIterator: abort();
case SortCategory::MapIterator: abort();
dwightguth marked this conversation as resolved.
Show resolved Hide resolved
}
}
return result;
Expand Down
11 changes: 10 additions & 1 deletion lib/codegen/CreateTerm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ target triple = "x86_64-unknown-linux-gnu"
%stringbuffer = type { i64, i64, %string* } ; 10-bit layout, 4-bit gc flags, 10 unused bits, 40-bit length, string length, current contents
%map = type { { i8 *, i64 } } ; immer::map
%set = type { { i8 *, i64 } } ; immer::set
%iter = type { { i8 *, i8 *, i32, [14 x i8**] }, { { i8 *, i64 } } } ; immer::map_iter / immer::set_iter
%setiter = type { { i8 *, i8 *, i32, [14 x i8**] }, { { i8 *, i64 } } } ; immer::set_iter
%mapiter = type { { i8 *, i8 *, i32, [14 x i8**] }, { { i8 *, i64 } } } ; immer::map_iter
%list = type { { i64, i32, i8 *, i8 * } } ; immer::flex_vector
%mpz = type { i32, i32, i64 * } ; mpz_t
%mpz_hdr = type { %blockheader, %mpz } ; 10-bit layout, 4-bit gc flags, 10 unused bits, 40-bit length, mpz_t
Expand Down Expand Up @@ -137,6 +138,8 @@ void addKompiledDirSymbol(
static std::string MAP_STRUCT = "map";
static std::string LIST_STRUCT = "list";
static std::string SET_STRUCT = "set";
static std::string SETITER_STRUCT = "setiter";
static std::string MAPITER_STRUCT = "mapiter";
static std::string INT_WRAPPER_STRUCT = "mpz_hdr";
static std::string INT_STRUCT = "mpz";
static std::string FLOAT_WRAPPER_STRUCT = "floating_hdr";
Expand All @@ -148,6 +151,8 @@ static std::string BLOCKHEADER_STRUCT = "blockheader";
llvm::Type *getParamType(ValueType sort, llvm::Module *Module) {
llvm::Type *type = getValueType(sort, Module);
switch (sort.cat) {
case SortCategory::SetIterator:
case SortCategory::MapIterator:
case SortCategory::Map:
case SortCategory::List:
case SortCategory::Set: type = llvm::PointerType::get(type, 1); break;
Expand All @@ -161,6 +166,8 @@ llvm::Type *getValueType(ValueType sort, llvm::Module *Module) {
case SortCategory::Map: return getTypeByName(Module, MAP_STRUCT);
case SortCategory::List: return getTypeByName(Module, LIST_STRUCT);
case SortCategory::Set: return getTypeByName(Module, SET_STRUCT);
case SortCategory::SetIterator: return getTypeByName(Module, SETITER_STRUCT);
case SortCategory::MapIterator: return getTypeByName(Module, MAPITER_STRUCT);
case SortCategory::Int:
return llvm::PointerType::get(getTypeByName(Module, INT_STRUCT), 1);
case SortCategory::Float:
Expand Down Expand Up @@ -340,6 +347,8 @@ llvm::Value *CreateTerm::createToken(ValueType sort, std::string contents) {
case SortCategory::Map:
case SortCategory::List:
case SortCategory::Set:
case SortCategory::SetIterator:
case SortCategory::MapIterator:
assert(false && "cannot create tokens of collection category");
case SortCategory::Int: {
llvm::Constant *global = Module->getOrInsertGlobal(
Expand Down
2 changes: 2 additions & 0 deletions lib/codegen/Debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ llvm::DIType *getDebugType(ValueType type, std::string typeName) {
types[typeName] = symbol;
return symbol;
case SortCategory::Uncomputed: abort();
case SortCategory::SetIterator: abort();
case SortCategory::MapIterator: abort();
}
}

Expand Down
63 changes: 15 additions & 48 deletions lib/codegen/Decision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,12 @@ void MakeIteratorNode::codegen(Decision *d) {
llvm::Value *arg = d->load(std::make_pair(collection, collectionType));
args.push_back(arg);
types.push_back(arg->getType());
llvm::Type *sretType = getTypeByName(d->Module, "iter");
llvm::Value *AllocSret = allocateTermNoReloc(sretType, d->CurrentBlock);
llvm::Type *sretType = type->getPointerElementType();
llvm::Value *AllocSret = allocateTerm(
{hookName == "set_iterator" ? SortCategory::SetIterator
: SortCategory::MapIterator,
0},
sretType, d->CurrentBlock, "koreAllocAlwaysGC");
dwightguth marked this conversation as resolved.
Show resolved Hide resolved
AllocSret->setName(name.substr(0, max_name_length));
args.insert(args.begin(), AllocSret);
types.insert(types.begin(), AllocSret->getType());
Expand Down Expand Up @@ -474,14 +478,8 @@ void LeafNode::codegen(Decision *d) {
getOrInsertFunction(
d->Module, "addSearchResult",
llvm::FunctionType::get(
llvm::Type::getVoidTy(d->Ctx),
{type,
llvm::PointerType::getUnqual(llvm::PointerType::get(type, 1)),
llvm::Type::getInt64PtrTy(d->Ctx),
llvm::Type::getInt64PtrTy(d->Ctx)},
false)),
{Call, d->ResultBuffer, d->ResultCount, d->ResultCapacity}, "",
d->CurrentBlock);
llvm::Type::getVoidTy(d->Ctx), {type}, false)),
{Call}, "", d->CurrentBlock);
setDebugLoc(Call2);
if (child != FailNode::get()) {
child->codegen(d);
Expand Down Expand Up @@ -646,7 +644,7 @@ void makeEvalOrAnywhereFunction(
int i = 0;
Decision codegen(
definition, block, fail, jump, choiceBuffer, choiceDepth, module,
returnSort, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
returnSort, nullptr, nullptr, nullptr);
for (auto val = matchFunc->arg_begin(); val != matchFunc->arg_end();
++val, ++i) {
val->setName("_" + std::to_string(i + 1));
Expand Down Expand Up @@ -798,16 +796,14 @@ void makeStepFunction(
KOREDefinition *definition, llvm::Module *module, DecisionNode *dt,
bool search) {
auto blockType = getValueType({SortCategory::Symbol, 0}, module);
auto bufType = llvm::PointerType::get(blockType, 1);
auto debugType
= getDebugType({SortCategory::Symbol, 0}, "SortGeneratedTopCell{}");
llvm::FunctionType *funcType;
std::string name;
if (search) {
name = "stepAll";
funcType = llvm::FunctionType::get(
bufType, {blockType, llvm::Type::getInt64PtrTy(module->getContext())},
false);
llvm::Type::getVoidTy(module->getContext()), {blockType}, false);
} else {
name = "step";
funcType = llvm::FunctionType::get(blockType, {blockType}, false);
Expand All @@ -817,10 +813,7 @@ void makeStepFunction(
resetDebugLoc();
if (search) {
initDebugFunction(
name, name,
getDebugFunctionType(
getPointerDebugType(debugType, "block **"),
{debugType, getPointerDebugType(getLongDebugType(), "uint64_t *")}),
name, name, getDebugFunctionType(getVoidDebugType(), {debugType}),
definition, matchFunc);
} else {
initDebugFunction(
Expand All @@ -841,30 +834,8 @@ void makeStepFunction(
llvm::AllocaInst *choiceBuffer, *choiceDepth;
llvm::IndirectBrInst *jump;

llvm::Value *resultBuffer = nullptr, *resultCount = nullptr,
*resultCapacity = nullptr;
if (search) {
resultBuffer = new llvm::AllocaInst(bufType, 0, "resultBuffer", block);
resultCount = matchFunc->arg_begin() + 1;
resultCapacity = new llvm::AllocaInst(
llvm::Type::getInt64Ty(module->getContext()), 0, "resultCapacity",
block);
}

insertCallToClear(block);

if (search) {
llvm::Value *initialBuffer = allocateTerm(
{SortCategory::Symbol, 0}, blockType, block, "koreAllocAlwaysGC");
new llvm::StoreInst(initialBuffer, resultBuffer, block);
new llvm::StoreInst(
llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 0),
resultCount, block);
new llvm::StoreInst(
llvm::ConstantInt::get(llvm::Type::getInt64Ty(module->getContext()), 1),
resultCapacity, block);
}

initChoiceBuffer(
dt, module, block, pre_stuck, fail, &choiceBuffer, &choiceDepth, &jump);

Expand All @@ -877,12 +848,10 @@ void makeStepFunction(
val->setName("_1");
Decision codegen(
definition, result, fail, jump, choiceBuffer, choiceDepth, module,
{SortCategory::Symbol, 0}, nullptr, nullptr, nullptr, resultBuffer,
resultCount, resultCapacity);
{SortCategory::Symbol, 0}, nullptr, nullptr, nullptr);
codegen.store(std::make_pair(val->getName().str(), val->getType()), val);
if (search) {
auto result = new llvm::LoadInst(bufType, resultBuffer, "", stuck);
llvm::ReturnInst::Create(module->getContext(), result, stuck);
llvm::ReturnInst::Create(module->getContext(), stuck);
} else {
llvm::ReturnInst::Create(module->getContext(), val, stuck);
}
Expand Down Expand Up @@ -949,8 +918,7 @@ void makeMatchReasonFunction(
val->setName("_1");
Decision codegen(
definition, block, fail, jump, choiceBuffer, choiceDepth, module,
{SortCategory::Symbol, 0}, FailSubject, FailPattern, FailSort, nullptr,
nullptr, nullptr);
{SortCategory::Symbol, 0}, FailSubject, FailPattern, FailSort);
codegen.store(std::make_pair(val->getName().str(), val->getType()), val);
llvm::ReturnInst::Create(module->getContext(), stuck);

Expand Down Expand Up @@ -1065,8 +1033,7 @@ void makeStepFunction(
i = 0;
Decision codegen(
definition, header, fail, jump, choiceBuffer, choiceDepth, module,
{SortCategory::Symbol, 0}, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr);
{SortCategory::Symbol, 0}, nullptr, nullptr, nullptr);
for (auto val : args) {
val->setName(res.residuals[i].occurrence.substr(0, max_name_length));
codegen.store(std::make_pair(val->getName().str(), val->getType()), val);
Expand Down
19 changes: 12 additions & 7 deletions lib/codegen/DecisionParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,27 +197,32 @@ class DTPreprocessor {

DecisionNode *makeIterator(yaml_node_t *node) {
std::string name = to_string(vec(get(node, "collection")));
llvm::Type *type = getParamType(
KORECompositeSort::getCategory(str(get(node, "sort"))), mod);
std::string cat = str(get(node, "sort"));
llvm::Type *type = getParamType(KORECompositeSort::getCategory(cat), mod);
std::string function = str(get(node, "function"));
auto child = (*this)(get(node, "next"));

return MakeIteratorNode::Create(
name, type, name + "_iter",
llvm::PointerType::getUnqual(getTypeByName(mod, "iter")), function,
child);
llvm::PointerType::get(
getTypeByName(mod, cat == "SET.Set" ? "setiter" : "mapiter"), 1),
dwightguth marked this conversation as resolved.
Show resolved Hide resolved
function, child);
}

DecisionNode *iterNext(yaml_node_t *node) {
std::string iterator = to_string(vec(get(node, "iterator"))) + "_iter";
std::string name = to_string(vec(get(node, "binding")));
llvm::Type *type = getParamType(
KORECompositeSort::getCategory(str(get(node, "sort"))), mod);
std::string cat = str(get(node, "sort"));
llvm::Type *type = getParamType(KORECompositeSort::getCategory(cat), mod);
std::string function = str(get(node, "function"));
auto child = (*this)(get(node, "next"));

return IterNextNode::Create(
iterator, llvm::PointerType::getUnqual(getTypeByName(mod, "iter")),
iterator,
llvm::PointerType::get(
getTypeByName(
mod, function == "set_iterator_next" ? "setiter" : "mapiter"),
1),
dwightguth marked this conversation as resolved.
Show resolved Hide resolved
name, type, function, child);
}

Expand Down
8 changes: 8 additions & 0 deletions lib/codegen/EmitConfigParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ static llvm::Value *getArgValue(
CaseBlock);
break;
case SortCategory::Uncomputed: abort();
case SortCategory::MapIterator: abort();
case SortCategory::SetIterator: abort();
}
return arg;
}
Expand Down Expand Up @@ -362,6 +364,8 @@ static std::pair<llvm::Value *, llvm::BasicBlock *> getEval(
break;
}
case SortCategory::Uncomputed: abort();
case SortCategory::MapIterator: abort();
case SortCategory::SetIterator: abort();
}
creator.getCurrentBlock()->getInstList().push_back(inst);
return std::make_pair(retval, creator.getCurrentBlock());
Expand Down Expand Up @@ -590,6 +594,8 @@ static void emitGetToken(KOREDefinition *definition, llvm::Module *module) {
case SortCategory::Variable:
case SortCategory::Symbol: break;
case SortCategory::Uncomputed: abort();
case SortCategory::MapIterator: abort();
case SortCategory::SetIterator: abort();
}
CurrentBlock = FalseBlock;
}
Expand Down Expand Up @@ -981,6 +987,8 @@ static void getVisitor(
break;
}
case SortCategory::Uncomputed: abort();
case SortCategory::MapIterator: abort();
case SortCategory::SetIterator: abort();
}
if (i != symbol->getArguments().size() - 1) {
llvm::CallInst::Create(
Expand Down
4 changes: 4 additions & 0 deletions lib/llvm/EmitGCLayoutInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ struct EmitGCLayoutInfo : public ModulePass {
cat.cat = SortCategory::List;
} else if (name == "set") {
cat.cat = SortCategory::Set;
} else if (name == "setiter") {
cat.cat = SortCategory::SetIterator;
} else if (name == "mapiter") {
cat.cat = SortCategory::SetIterator;
} else if (name == "mpz") {
cat.cat = SortCategory::Int;
} else if (name == "floating") {
Expand Down
10 changes: 10 additions & 0 deletions runtime/alloc/alloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ koreAllocAlwaysGC_p1s_lists(size_t requested) {
return (list *)koreAllocAlwaysGC(requested);
}

__attribute__((always_inline)) setiter *
koreAllocAlwaysGC_p1s_setiters(size_t requested) {
return (setiter *)koreAllocAlwaysGC(requested);
}

__attribute__((always_inline)) mapiter *
koreAllocAlwaysGC_p1s_mapiters(size_t requested) {
return (mapiter *)koreAllocAlwaysGC(requested);
}

__attribute__((always_inline)) block *
koreAllocAlwaysGC_p1s_blocks(size_t requested) {
return (block *)koreAllocAlwaysGC(requested);
Expand Down
Loading