Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/tools/pattern-gen/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ int main(int argc, char **argv) {
TokenStream Ts(InputFilename.c_str());
LLVMContext Ctx;
auto Mod = std::make_unique<Module>("mod", Ctx);
auto Instrs = ParseCoreDSL2(Ts, (XLen == 64), Mod.get(), NoExtend);
auto Instrs = ParseCoreDSL2FrontEnd(Ts);
GenerateBehaviorIR(Instrs, (XLen == 64), Mod.get(), NoExtend);

if (irOut) {
std::string Str;
Expand Down
3 changes: 3 additions & 0 deletions llvm/tools/pattern-gen/lib/InstrInfo.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include "llvm/ADT/SmallVector.h"
#include "Token.hpp"
#include <cstdint>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -44,6 +45,8 @@ struct CDSLInstr

llvm::SmallVector<Field, 4> fields;
llvm::SmallVector<FieldFrag, 8> frags;
llvm::SmallVector<Token, 64> behaviorTokens;
int behaviorLine = 1;
};

std::string EncodingToTablgen(CDSLInstr const& instr);
Expand Down
73 changes: 51 additions & 22 deletions llvm/tools/pattern-gen/lib/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1360,8 +1360,32 @@ void ParseArguments(TokenStream &ts, CDSLInstr &instr) {
pop_cur(ts, Semicolon);
}

void ParseBehaviour(TokenStream &ts, CDSLInstr &instr, llvm::Module *mod,
Token const &ident) {
void ParseBehaviour(TokenStream &ts, CDSLInstr &instr) {
pop_cur(ts, BehaviorKeyword);
pop_cur(ts, Colon);
instr.behaviorLine = ts.lineNumber;

int scopeDepth = 0;
while (ts.Peek().type != None) {
auto t = ts.Peek();
if (t.type == CBrClose && scopeDepth == 0)
break;

t = ts.Pop();
instr.behaviorTokens.push_back(t);

if (t.type == CBrOpen)
++scopeDepth;
else if (t.type == CBrClose)
--scopeDepth;
}
}

static void GenerateInstructionBehaviorIR(CDSLInstr &instr, llvm::Module *mod) {
TokenStream ts(std::string("<behavior:") + instr.name + ">",
std::vector<Token>(instr.behaviorTokens.begin(),
instr.behaviorTokens.end()),
instr.behaviorLine);
auto &ctx = mod->getContext();
auto ptrT = llvm::PointerType::get(ctx, 0);
auto immT = regT;
Expand Down Expand Up @@ -1397,28 +1421,20 @@ void ParseBehaviour(TokenStream &ts, CDSLInstr &instr, llvm::Module *mod,
auto fType =
llvm::FunctionType::get(llvm::Type::getVoidTy(ctx), argTypes, false);

pop_cur(ts, BehaviorKeyword);
pop_cur(ts, Colon);

llvm::Function *func = llvm::Function::Create(
fType, llvm::GlobalValue::ExternalLinkage,
std::string("impl") + std::string(ident.ident.str), mod);
std::string("impl") + instr.name, mod);

for (size_t i = 0; i < argNames.size(); i++)
func->getArg(i)->setName(argNames[i]);

// For vectorization to work, we must assume that
// the destination does not overlap with sources.
// For simulators using this generated code, this means
// that rd has to be a pointer to a temporary variable.
for (size_t i = 0; i < curInstr->fields.size(); i++)
if (curInstr->fields[i].type & CDSLInstr::OUT)
func->getArg(i)->addAttr(llvm::Attribute::NoAlias);

entry = llvm::BasicBlock::Create(ctx, "", func);
llvm::IRBuilder<> build(entry);

// Generate range assumes for immediates
for (size_t i = 0; i < argBitLens.size(); i++)
if (argBitLens[i] != -1) {
auto *arg = func->getArg(i);
Expand All @@ -1431,15 +1447,13 @@ void ParseBehaviour(TokenStream &ts, CDSLInstr &instr, llvm::Module *mod,
}

ParseStatement(ts, func, build);
if (ts.Peek().type != None)
syntax_error(ts);
build.CreateRetVoid();
}

std::vector<CDSLInstr> ParseCoreDSL2(TokenStream &ts, bool is64Bit,
llvm::Module *mod, bool NoExtend) {
std::vector<CDSLInstr> ParseCoreDSL2FrontEnd(TokenStream &ts) {
std::vector<CDSLInstr> instrs;
xlen = is64Bit ? 64 : 32;
NoExtend_ = NoExtend;
regT = llvm::Type::getIntNTy(mod->getContext(), xlen);

while (ts.Peek().type != None) {
bool parseBoilerplate =
Expand All @@ -1458,11 +1472,6 @@ std::vector<CDSLInstr> ParseCoreDSL2(TokenStream &ts, bool is64Bit,
while (ts.Peek().type != CBrClose && ts.Peek().type != None) {
reset_globals();

// add XLEN and RFS as constants for now.
add_variable(ts, ts.GetIdentIdx("XLEN"),
Value{llvm::ConstantInt::get(regT, xlen)});
add_variable(ts, ts.GetIdentIdx("RFS"),
Value{llvm::ConstantInt::get(regT, 32)});
++PatternGenNumInstructionsParsed;

Token ident = pop_cur(ts, Identifier);
Expand All @@ -1474,7 +1483,7 @@ std::vector<CDSLInstr> ParseCoreDSL2(TokenStream &ts, bool is64Bit,
ParseOperands(ts, instr);
ParseEncoding(ts, instr);
ParseArguments(ts, instr);
ParseBehaviour(ts, instr, mod, ident);
ParseBehaviour(ts, instr);

pop_cur(ts, CBrClose);
instrs.push_back(instr);
Expand All @@ -1487,3 +1496,23 @@ std::vector<CDSLInstr> ParseCoreDSL2(TokenStream &ts, bool is64Bit,
}
return instrs;
}

void GenerateBehaviorIR(std::vector<CDSLInstr> &instrs, bool is64Bit,
llvm::Module *mod, bool NoExtend) {
xlen = is64Bit ? 64 : 32;
NoExtend_ = NoExtend;
regT = llvm::Type::getIntNTy(mod->getContext(), xlen);

for (auto &instr : instrs) {
reset_globals();
curInstr = &instr;

TokenStream ts("<behavior-constants>", std::vector<Token>{}, instr.behaviorLine);
add_variable(ts, ts.GetIdentIdx("XLEN"),
Value{llvm::ConstantInt::get(regT, xlen)});
add_variable(ts, ts.GetIdentIdx("RFS"),
Value{llvm::ConstantInt::get(regT, 32)});

GenerateInstructionBehaviorIR(instr, mod);
}
}
5 changes: 3 additions & 2 deletions llvm/tools/pattern-gen/lib/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
#include "TokenStream.hpp"
#include <llvm/IR/Module.h>

std::vector<CDSLInstr> ParseCoreDSL2(TokenStream &ts, bool is64Bit,
llvm::Module *mod, bool NoExtend);
std::vector<CDSLInstr> ParseCoreDSL2FrontEnd(TokenStream &ts);
void GenerateBehaviorIR(std::vector<CDSLInstr> &instrs, bool is64Bit,
llvm::Module *mod, bool NoExtend);
16 changes: 16 additions & 0 deletions llvm/tools/pattern-gen/lib/TokenStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ Token TokenStream::Pop()
return t;
}

if (replayTokens.has_value())
{
if (replayIdx >= replayTokens->size())
return Token(None);
return (*replayTokens)[replayIdx++];
}

size_t len = src.length();
const char* srcC = src.c_str();

Expand Down Expand Up @@ -212,3 +219,12 @@ std::string_view TokenStream::GetIdent(unsigned identIdx)
}

TokenStream::TokenStream(std::string&& srcPath) : path(srcPath), src(read_file_as_str(srcPath)) {}

TokenStream::TokenStream(std::string&& srcPath, std::vector<Token> &&tokens,
int startLine)
: path(srcPath), src(""), lineNumber(startLine),
replayTokens(std::move(tokens)) {
for (const auto &t : *replayTokens)
if (t.type == Identifier)
strings[t.ident.str] = t.ident.idx + NUM_KEYWORDS;
}
4 changes: 4 additions & 0 deletions llvm/tools/pattern-gen/lib/TokenStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string>
#include <optional>
#include <map>
#include <vector>
#include "Token.hpp"

struct TokenStream
Expand Down Expand Up @@ -29,9 +30,12 @@ struct TokenStream
std::make_pair("unsigned", UnsignedKeyword-TOK_KW_START),
};
const size_t NUM_KEYWORDS = strings.size();
std::optional<std::vector<Token>> replayTokens;
size_t replayIdx = 0;

public:
TokenStream (std::string&& srcPath);
TokenStream (std::string&& srcPath, std::vector<Token> &&tokens, int startLine = 1);
Token Pop();
Token Peek();
unsigned GetIdentIdx(std::string_view ident);
Expand Down