diff --git a/llvm/tools/pattern-gen/Main.cpp b/llvm/tools/pattern-gen/Main.cpp index 62eea631137a..8bdefcc44ee1 100644 --- a/llvm/tools/pattern-gen/Main.cpp +++ b/llvm/tools/pattern-gen/Main.cpp @@ -126,7 +126,8 @@ int main(int argc, char **argv) { TokenStream Ts(InputFilename.c_str()); LLVMContext Ctx; auto Mod = std::make_unique("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; diff --git a/llvm/tools/pattern-gen/lib/InstrInfo.hpp b/llvm/tools/pattern-gen/lib/InstrInfo.hpp index ba741d6fb628..b5beef4f9e40 100644 --- a/llvm/tools/pattern-gen/lib/InstrInfo.hpp +++ b/llvm/tools/pattern-gen/lib/InstrInfo.hpp @@ -1,5 +1,6 @@ #pragma once #include "llvm/ADT/SmallVector.h" +#include "Token.hpp" #include #include #include @@ -44,6 +45,8 @@ struct CDSLInstr llvm::SmallVector fields; llvm::SmallVector frags; + llvm::SmallVector behaviorTokens; + int behaviorLine = 1; }; std::string EncodingToTablgen(CDSLInstr const& instr); diff --git a/llvm/tools/pattern-gen/lib/Parser.cpp b/llvm/tools/pattern-gen/lib/Parser.cpp index 81d65a4739e2..be762e7f74cf 100644 --- a/llvm/tools/pattern-gen/lib/Parser.cpp +++ b/llvm/tools/pattern-gen/lib/Parser.cpp @@ -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("", + std::vector(instr.behaviorTokens.begin(), + instr.behaviorTokens.end()), + instr.behaviorLine); auto &ctx = mod->getContext(); auto ptrT = llvm::PointerType::get(ctx, 0); auto immT = regT; @@ -1397,20 +1421,13 @@ 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); @@ -1418,7 +1435,6 @@ void ParseBehaviour(TokenStream &ts, CDSLInstr &instr, llvm::Module *mod, 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); @@ -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 ParseCoreDSL2(TokenStream &ts, bool is64Bit, - llvm::Module *mod, bool NoExtend) { +std::vector ParseCoreDSL2FrontEnd(TokenStream &ts) { std::vector instrs; - xlen = is64Bit ? 64 : 32; - NoExtend_ = NoExtend; - regT = llvm::Type::getIntNTy(mod->getContext(), xlen); while (ts.Peek().type != None) { bool parseBoilerplate = @@ -1458,11 +1472,6 @@ std::vector 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); @@ -1474,7 +1483,7 @@ std::vector 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); @@ -1487,3 +1496,23 @@ std::vector ParseCoreDSL2(TokenStream &ts, bool is64Bit, } return instrs; } + +void GenerateBehaviorIR(std::vector &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("", std::vector{}, 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); + } +} diff --git a/llvm/tools/pattern-gen/lib/Parser.hpp b/llvm/tools/pattern-gen/lib/Parser.hpp index 19cbcd62ca98..3a0d5fbc9f6b 100644 --- a/llvm/tools/pattern-gen/lib/Parser.hpp +++ b/llvm/tools/pattern-gen/lib/Parser.hpp @@ -3,5 +3,6 @@ #include "TokenStream.hpp" #include -std::vector ParseCoreDSL2(TokenStream &ts, bool is64Bit, - llvm::Module *mod, bool NoExtend); +std::vector ParseCoreDSL2FrontEnd(TokenStream &ts); +void GenerateBehaviorIR(std::vector &instrs, bool is64Bit, + llvm::Module *mod, bool NoExtend); diff --git a/llvm/tools/pattern-gen/lib/TokenStream.cpp b/llvm/tools/pattern-gen/lib/TokenStream.cpp index 9ea2b5e38794..83094e6281df 100644 --- a/llvm/tools/pattern-gen/lib/TokenStream.cpp +++ b/llvm/tools/pattern-gen/lib/TokenStream.cpp @@ -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(); @@ -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 &&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; +} diff --git a/llvm/tools/pattern-gen/lib/TokenStream.hpp b/llvm/tools/pattern-gen/lib/TokenStream.hpp index fae92a9fe519..dd5c8da6b961 100644 --- a/llvm/tools/pattern-gen/lib/TokenStream.hpp +++ b/llvm/tools/pattern-gen/lib/TokenStream.hpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "Token.hpp" struct TokenStream @@ -29,9 +30,12 @@ struct TokenStream std::make_pair("unsigned", UnsignedKeyword-TOK_KW_START), }; const size_t NUM_KEYWORDS = strings.size(); + std::optional> replayTokens; + size_t replayIdx = 0; public: TokenStream (std::string&& srcPath); + TokenStream (std::string&& srcPath, std::vector &&tokens, int startLine = 1); Token Pop(); Token Peek(); unsigned GetIdentIdx(std::string_view ident);