diff --git a/0001-matrix_mult_ident-commit.patch b/0001-matrix_mult_ident-commit.patch new file mode 100644 index 0000000000000000000000000000000000000000..74f9feb5f23703f168d0d537b5efbcf37d852b1f --- /dev/null +++ b/0001-matrix_mult_ident-commit.patch @@ -0,0 +1,649 @@ +From 35f8e4c62a5dfa9ffe948ef812fc4b5d1e586891 Mon Sep 17 00:00:00 2001 +From: yuanshaobai <2659799534@qq.com> +Date: Sat, 17 Sep 2022 16:11:23 +0800 +Subject: [PATCH] matrix_mult_ident commit + +--- + clang/lib/CodeGen/CGMatrixInfo.cpp | 333 +++++++++++++++++++++++++ + clang/lib/CodeGen/CGMatrixInfo.h | 20 ++ + clang/lib/CodeGen/CGStmt.cpp | 30 ++- + clang/lib/CodeGen/CMakeLists.txt | 1 + + clang/test/CodeGen/Matrix_mult_ident.c | 176 +++++++++++++ + 5 files changed, 553 insertions(+), 7 deletions(-) + create mode 100644 clang/lib/CodeGen/CGMatrixInfo.cpp + create mode 100644 clang/lib/CodeGen/CGMatrixInfo.h + create mode 100644 clang/test/CodeGen/Matrix_mult_ident.c + +diff --git a/clang/lib/CodeGen/CGMatrixInfo.cpp b/clang/lib/CodeGen/CGMatrixInfo.cpp +new file mode 100644 +index 000000000000..5cc4d9fa97bf +--- /dev/null ++++ b/clang/lib/CodeGen/CGMatrixInfo.cpp +@@ -0,0 +1,333 @@ ++ ++#include ++#include "clang/Frontend/FrontendActions.h" ++#include "clang/Tooling/CommonOptionsParser.h" ++#include "clang/Tooling/Tooling.h" ++#include "llvm/Support/CommandLine.h" ++#include ++#include "CGMatrixInfo.h" ++#include "queue" ++ ++ ++using namespace std; ++using namespace clang::tooling; ++using namespace llvm; ++static llvm::cl::OptionCategory MyToolCategory("matrix_ident options"); ++ ++#include "clang/ASTMatchers/ASTMatchers.h" ++#include "clang/ASTMatchers/ASTMatchFinder.h" ++ ++using namespace clang; ++using namespace clang::ast_matchers; ++ ++queue matrix_mult_info; ++ ++StatementMatcher MatrixMatcher = ++forStmt(hasIncrement(unaryOperator().bind("firstop")), ++ hasLoopInit(declStmt(hasSingleDecl(varDecl(hasInitializer(integerLiteral().bind("firstvar1"))).bind("firstvar")))), ++ hasCondition(binaryOperator(hasLHS(implicitCastExpr(hasSourceExpression(declRefExpr()))),hasRHS(integerLiteral().bind("firstvar2"))).bind("firstcondop")), ++ hasBody(compoundStmt(hasAnySubstatement( ++ forStmt(hasIncrement(unaryOperator().bind("secondop")), ++ hasLoopInit(declStmt(hasSingleDecl(varDecl(hasInitializer(integerLiteral().bind("secondvar1"))).bind("secondvar")))), ++ hasCondition(binaryOperator(hasLHS(implicitCastExpr(hasSourceExpression(declRefExpr()))),hasRHS(integerLiteral().bind("secondvar2"))).bind("secondcondop")), ++ hasBody(compoundStmt(hasAnySubstatement( ++ forStmt(hasIncrement(unaryOperator().bind("thirdop")), ++ hasLoopInit(declStmt(hasSingleDecl(varDecl(hasInitializer(integerLiteral().bind("thirdvar1"))).bind("thirdvar")))), ++ hasCondition(binaryOperator(hasLHS(implicitCastExpr(hasSourceExpression(declRefExpr()))),hasRHS(integerLiteral().bind("thirdvar2"))).bind("thirdcondop")), ++ hasBody(compoundStmt( ++ forEach(binaryOperator(forEachDescendant( ++ binaryOperator( ++ hasOperatorName("*"), ++ hasLHS(implicitCastExpr(hasSourceExpression( ++ arraySubscriptExpr( ++ hasBase(implicitCastExpr( ++ hasSourceExpression(arraySubscriptExpr( ++ hasIndex(implicitCastExpr( ++ hasSourceExpression(declRefExpr(to(varDecl().bind("matrixA_idx1"))) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ), ++ hasIndex(implicitCastExpr( ++ hasSourceExpression(declRefExpr(declRefExpr(to(varDecl().bind("matrixA_idx2"))))) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ) ++ , ++ hasRHS(implicitCastExpr(hasSourceExpression( ++ arraySubscriptExpr( ++ hasBase(implicitCastExpr( ++ hasSourceExpression(arraySubscriptExpr( ++ hasIndex(implicitCastExpr( ++ hasSourceExpression(declRefExpr(declRefExpr(to(varDecl().bind("matrixB_idx1")))) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ), ++ hasIndex(implicitCastExpr( ++ hasSourceExpression(declRefExpr(declRefExpr(to(varDecl().bind("matrixB_idx2"))))) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ) ++ ).bind("operator"))))) ++ ) ++ ).bind("thirdfor"))) ++ ) ++ ++ ++ ).bind("secondfor"))) ++ ) ++ ++ ++ ).bind("firstfor"); ++ ++ ++ ++ ++class Matrix_ident : public MatchFinder::MatchCallback { ++public: ++ ++ ++ virtual void run(const MatchFinder::MatchResult& Result)override ++ { ++ isMatrix = false; ++ ++ VarDecl const * MatrixA_Idx1 = Result.Nodes.getNodeAs("matrixA_idx1"); ++ VarDecl const * MatrixA_Idx2 = Result.Nodes.getNodeAs("matrixA_idx2"); ++ VarDecl const * MatrixB_Idx1 = Result.Nodes.getNodeAs("matrixB_idx1"); ++ VarDecl const * MatrixB_Idx2 = Result.Nodes.getNodeAs("matrixB_idx2"); ++ BinaryOperator const * F_condop = Result.Nodes.getNodeAs("firstcondop"); ++ BinaryOperator const * S_condop = Result.Nodes.getNodeAs("secondcondop"); ++ BinaryOperator const * T_condop = Result.Nodes.getNodeAs("thirdcondop"); ++ UnaryOperator const * F_op =Result.Nodes.getNodeAs("firstop"); ++ UnaryOperator const * S_op =Result.Nodes.getNodeAs("secondop"); ++ UnaryOperator const * T_op =Result.Nodes.getNodeAs("thirdop"); ++ ++ ++ VarDecl const * FirstForCondVar = Result.Nodes.getNodeAs("firstvar"); ++ VarDecl const * SecondForCondVar = Result.Nodes.getNodeAs("secondvar"); ++ VarDecl const * ThirdForCondVar = Result.Nodes.getNodeAs("thirdvar"); ++ ++ ++ bool is_Firstvar_equal = false ,is_Secondvar_equal = false ,is_Thirdvar_equal = false; ++ string M_A1,M_A2,M_B1,M_B2,F_name,S_name,T_name; ++ M_A1 = MatrixA_Idx1->getName().str(); ++ M_A2 = MatrixA_Idx2->getName().str(); ++ M_B1 = MatrixB_Idx1->getName().str(); ++ M_B2 = MatrixB_Idx2->getName().str(); ++ F_name = FirstForCondVar->getName().str(); ++ S_name = SecondForCondVar->getName().str(); ++ T_name = ThirdForCondVar->getName().str(); ++ ++ if(F_name == M_A1 ||F_name == M_A2 ||F_name == M_B1 ||F_name == M_B2 ) ++ is_Firstvar_equal=true; ++ if(S_name == M_A1 ||S_name == M_A2 ||S_name == M_B1 ||S_name == M_B2 ) ++ is_Secondvar_equal=true; ++ if(T_name == M_A1 ||T_name == M_A2 ||T_name == M_B1 ||T_name == M_B2 ) ++ is_Thirdvar_equal=true; ++ ++ string F_condopStr = F_condop->getOpcodeStr().str(); ++ string S_condopStr = S_condop->getOpcodeStr().str(); ++ string T_condopStr = T_condop->getOpcodeStr().str(); ++ string F_opStr = F_op->getOpcodeStr(F_op->getOpcode()).str(); ++ string S_opStr = S_op->getOpcodeStr(S_op->getOpcode()).str(); ++ string T_opStr = T_op->getOpcodeStr(T_op->getOpcode()).str(); ++ ++ if(is_Firstvar_equal && is_Secondvar_equal && is_Thirdvar_equal && M_A1 != M_A2 && M_B1 != M_B2) ++ { ++ if((F_condopStr == "<" && F_opStr == "++") || (F_condopStr == ">" && F_opStr == "--")) ++ if((S_condopStr == "<" && S_opStr == "++") || (S_condopStr == ">" && S_opStr == "--")) ++ if((T_condopStr == "<" && T_opStr == "++") || (T_condopStr == ">" && T_opStr == "--")) ++ isMatrix = true; ++ } ++ ++ ++ if(isMatrix==true) ++ { ++ bool a_transpose = false,b_transpose = false; ++ ++ int a_rows = 0 , b_rows= 0 , a_columns = 0 , b_columns = 0; ++ ++ IntegerLiteral const * FirstVar1_ = Result.Nodes.getNodeAs("firstvar1"); ++ IntegerLiteral const * FirstVar2_ = Result.Nodes.getNodeAs("firstvar2"); ++ IntegerLiteral const * SecondVar1_ = Result.Nodes.getNodeAs("secondvar1"); ++ IntegerLiteral const * SecondVar2_ = Result.Nodes.getNodeAs("secondvar2"); ++ IntegerLiteral const * ThirdVar1_ = Result.Nodes.getNodeAs("thirdvar1"); ++ IntegerLiteral const * ThirdVar2_ = Result.Nodes.getNodeAs("thirdvar2"); ++ ++ if(M_A2 == M_B1) {a_transpose = false; b_transpose = false;} ++ if(M_A2 == M_B2) {a_transpose = false; b_transpose = true;} ++ if(M_A1 == M_B1) {a_transpose = true; b_transpose = false;} ++ if(M_A1 == M_B2) {a_transpose = true; b_transpose = true;} ++ ++ ++ ++ int FirstVar1 = FirstVar1_->getValue().getSExtValue(); ++ int FirstVar2 = FirstVar2_->getValue().getSExtValue(); ++ int SecondVar1 = SecondVar1_->getValue().getSExtValue(); ++ int SecondVar2 = SecondVar2_->getValue().getSExtValue(); ++ int ThirdVar1 = ThirdVar1_->getValue().getSExtValue(); ++ int ThirdVar2 = ThirdVar2_->getValue().getSExtValue(); ++ ++ int F_f = 1; ++ int S_f = 1; ++ int T_f = 1; ++ ++ if(F_opStr=="--") F_f = -1; ++ if(S_opStr=="--") S_f = -1; ++ if(T_opStr=="--") T_f = -1; ++ ++ ++ ++ if(M_A1 == F_name) a_rows = (FirstVar2 - FirstVar1) * F_f; ++ if(M_A1 == S_name) a_rows = (SecondVar2 - SecondVar1) * S_f; ++ if(M_A1 == T_name) a_rows = (ThirdVar2 - ThirdVar1) * T_f; ++ if(M_A2 == F_name) a_columns = (FirstVar2 - FirstVar1) * F_f; ++ if(M_A2 == S_name) a_columns = (SecondVar2 - SecondVar1) * S_f; ++ if(M_A2 == T_name) a_columns = (ThirdVar2 - ThirdVar1) * T_f; ++ if(M_B1 == F_name) b_rows = (FirstVar2 - FirstVar1) * F_f; ++ if(M_B1 == S_name) b_rows = (SecondVar2 - SecondVar1) * S_f; ++ if(M_B1 == T_name) b_rows = (ThirdVar2 - ThirdVar1) * T_f;; ++ if(M_B2 == F_name) b_columns = (FirstVar2 - FirstVar1) * F_f; ++ if(M_B2 == S_name) b_columns = (SecondVar2 - SecondVar1) * S_f;; ++ if(M_B2 == T_name) b_columns = (ThirdVar2 - ThirdVar1) * T_f; ++ ++ ++ ++ int t = 0; ++ if(a_transpose == true){ ++ t = a_rows ; a_rows = a_columns; a_columns = t; ++ } ++ if(b_transpose == true){ ++ t = b_rows ; b_rows = b_columns; b_columns = t; ++ } ++ ++ ++ ++ Metadata_print(a_rows, a_columns, b_rows, b_columns, a_transpose, b_transpose); ++ ++ set_info(); ++ ++ } ++ //else cout<<"is not a martix"< ForAttrs) { + JumpDest LoopExit = getJumpDestInCurrentScope("for.end"); +- +- LexicalScope ForScope(*this, S.getSourceRange()); +- ++ ASTContext &act = CGM.getContext(); ++ Matrix_ident_action Maction; ++ Maction.Matrix_mult_ident(S,act); ++ LexicalScope ForScope(*this, S.getSourceRange()); + // Evaluate the first part before the loop. + if (S.getInit()) + EmitStmt(S.getInit()); +- + // Start the loop with a block that tests the condition. + // If there's an increment, the continue scope will be overwritten + // later. + JumpDest CondDest = getJumpDestInCurrentScope("for.cond"); + llvm::BasicBlock *CondBlock = CondDest.getBlock(); + EmitBlock(CondBlock); +- ++ ++ if(Maction.has_Matrix()) ++ { ++ while(!Maction.is_info_queue_empty()) ++ { ++ std::string metadata_name = "Matrix_mult_ident"; ++ setmetadata_count++; ++ metadata_name = metadata_name+std::to_string(setmetadata_count); ++ llvm::LLVMContext & lct =CGM.getLLVMContext(); ++ std::string s = Maction.get_info(); ++ s += " identnum:"; ++ s += std::to_string(setmetadata_count); ++ llvm::MDNode * N = llvm::MDNode::get(lct, llvm::MDString::get(lct, s)); ++ llvm::Function * F = CondBlock->getParent(); ++ F->setMetadata(metadata_name, N); ++ } ++ } + Expr::EvalResult Result; + bool CondIsConstInt = + !S.getCond() || S.getCond()->EvaluateAsInt(Result, getContext()); +@@ -1076,7 +1093,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, + + // As long as the condition is true, iterate the loop. + llvm::BasicBlock *ForBody = createBasicBlock("for.body"); +- + // C99 6.8.5p2/p4: The first substatement is executed if the expression + // compares unequal to 0. The condition must be a scalar type. + llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); +diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt +index 0bb5abcf6045..41a2827e6a9f 100644 +--- a/clang/lib/CodeGen/CMakeLists.txt ++++ b/clang/lib/CodeGen/CMakeLists.txt +@@ -63,6 +63,7 @@ add_clang_library(clangCodeGen + CGOpenMPRuntimeGPU.cpp + CGRecordLayoutBuilder.cpp + CGStmt.cpp ++ CGMatrixInfo.cpp + CGStmtOpenMP.cpp + CGVTT.cpp + CGVTables.cpp +diff --git a/clang/test/CodeGen/Matrix_mult_ident.c b/clang/test/CodeGen/Matrix_mult_ident.c +new file mode 100644 +index 000000000000..84ff0c26c80c +--- /dev/null ++++ b/clang/test/CodeGen/Matrix_mult_ident.c +@@ -0,0 +1,176 @@ ++// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -I%p %s -o - | FileCheck %s ++ ++void testfoo() ++{ ++ int A[3][3]={1,2,3,4,5,6,7,8,9}; ++ int B[3][3]={1,2,3,4,5,6,7,8,9}; ++ int C[3][3]; ++ int D[3][3]; ++ ++ //四种转置情况样例 ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[m][k] * B[k][n]; ++ } ++ } ++ } ++//CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:0 identnum:1"} ++ ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[k][m] * B[k][n]; ++ } ++ } ++ } ++//CHECK: !{!"A_rows:3 A_columns:3 A_transpose:1 B_rows:3 B_columns:3 B_transpose:0 identnum:2"} ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[m][k] * B[n][k]; ++ } ++ } ++ } ++//CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:1 identnum:3"} ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++//CHECK: !{!"A_rows:3 A_columns:3 A_transpose:1 B_rows:3 B_columns:3 B_transpose:1 identnum:4"} ++ //行列不相等矩阵乘 ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 2; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 1; k++) { ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++//CHECK: !{!"A_rows:3 A_columns:1 A_transpose:1 B_rows:1 B_columns:2 B_transpose:1 identnum:5"} ++ //行列不相等,for循环索引交换矩阵 ++ for (int n = 0; n < 3; n++) { ++ for (int k = 0; k < 2; k++) { ++ C[n][k] = 0; ++ for (int m = 0; m < 1; m++) { ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++//CHECK: !{!"A_rows:1 A_columns:2 A_transpose:1 B_rows:2 B_columns:3 B_transpose:1 identnum:6"} ++ ++ //复合算式中的矩阵乘识别 ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ D[m][n] = 3*C[m][n]; ++ for (int k = 0; k < 3; k++) { ++ D[m][n] += 2*(A[m][k] * B[k][n]); ++ } ++ } ++ } ++//CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:0 identnum:7"} ++ //复合算式,--符号矩阵乘识别 ++ for (int m = 2; m > 0; m--) { ++ for (int n = 2; n > 0; n--) { ++ D[m][n] = 3*C[m][n]; ++ for (int k = 0; k < 3; k++) { ++ D[m][n] += 2*(A[m][k] * B[k][n]); ++ } ++ } ++ } ++//CHECK: !{!"A_rows:2 A_columns:3 A_transpose:0 B_rows:3 B_columns:2 B_transpose:0 identnum:8"} ++ //一个三重循环下有多个矩阵乘 ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[m][k] * B[k][n]; ++ C[m][n] += A[m][k] * B[k][n]; ++ } ++ } ++ } ++ //CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:0 identnum:9"} ++ //CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:0 identnum:10"} ++ //一个算式内有多个矩阵乘 ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[m][k] * B[k][n]+A[m][k] * B[k][n]; ++ } ++ } ++ } ++ //CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:0 identnum:11"} ++ //CHECK: !{!"A_rows:3 A_columns:3 A_transpose:0 B_rows:3 B_columns:3 B_transpose:0 identnum:12"} ++ //参数不符合反例 ++ for (int m = 2; m > 0; m--) { ++ for (int n = 2; n > 0; n--) { ++ D[m][n] = 3*C[m][n]; ++ for (int k = 0; k < 3; k++) { ++ D[m][n] += 2*(A[m][m] * B[k][n]); ++ } ++ } ++ } ++ //循环索引与参数不符合反例 ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int g = 0; g < 3; g++) { ++ int k; ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++ //过多循环的非矩阵乘反例 ++ for (int m = 0; m < 3; m++) { ++ for (int j = 0; j < 3; j++) ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) { ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++ ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) ++ for (int j = 0; j < 3; j++){ ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++ ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int j = 0; j < 3; j++) ++ for (int k = 0; k < 3; k++) ++ { ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++ //循环在上的正例 ++ for (int j = 0; j < 3; j++) ++ for (int m = 0; m < 3; m++) { ++ for (int n = 0; n < 3; n++) { ++ C[m][n] = 0; ++ for (int k = 0; k < 3; k++) ++ { ++ C[m][n] += A[k][m] * B[n][k]; ++ } ++ } ++ } ++//CHECK !{!"A_rows:3 A_columns:3 A_transpose:1 B_rows:3 B_columns:3 B_transpose:1 identnum:13"} ++} ++ ++ +-- +2.32.1 (Apple Git-133) + diff --git a/llvm.spec b/llvm.spec index 518d98dd13162e0105805f90df2447330debb6d5..de492afb9ece8287a85952a2b88abe27fe97b762 100644 --- a/llvm.spec +++ b/llvm.spec @@ -1,6 +1,6 @@ Name: llvm Version: 12.0.1 -Release: 3 +Release: 4 Summary: The Low Level Virtual Machine License: NCSA URL: http://llvm.org @@ -9,6 +9,7 @@ Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{versio BuildRequires: gcc gcc-c++ cmake ninja-build zlib-devel libffi-devel ncurses-devel libstdc++-static BuildRequires: python3-sphinx binutils-devel valgrind-devel libedit-devel python3-devel BuildRequires: python3-recommonmark +Patch0: 0001-matrix_mult_ident-commit.patch %description LLVM is a compiler infrastructure designed for compile-time, link-time, @@ -196,6 +197,12 @@ fi %{_mandir}/man1/* %changelog +* Sat Sep 17 2022 yuanshaobai <2659799534@qq.com> - 12.0.1-4 +- Type: enhancement +- ID: NA +- SUG: NA +- DESC: Add Matrix multiplication recognition function + * Tue Aug 23 2022 guopeilin - 12.0.1-3 - Type: enhancement - ID: NA