From b01c06e0fd4cd2e7e775b01f255ca58122846d54 Mon Sep 17 00:00:00 2001 From: yjmstr Date: Thu, 27 Feb 2025 10:24:29 +0800 Subject: [PATCH 1/2] patternDetect: add pattern detect for (1<child.size(); i ++) { if (top->child[i]) s.push(std::make_tuple(top->child[i], top, i)); } @@ -119,4 +120,4 @@ void graph::exprOpt() { } reconnectAll(); -} +} \ No newline at end of file diff --git a/src/patternDetect.cpp b/src/patternDetect.cpp index 8adf5e9e..cdb1411b 100644 --- a/src/patternDetect.cpp +++ b/src/patternDetect.cpp @@ -22,7 +22,27 @@ static ENode* isDshlOne(ENode* enode) { static bool isBitsOne(ENode* enode) { return (enode->opType == OP_BITS && enode->values[0] == enode->values[1]); } -bool checkPatern1(Node* node) { +// [(1 << expr) & 1] -> (expr == 0) +// if (pattern == (A & 1)) return A +// else return nullptr +static ENode* isBitAndOne(ENode* enode) { + if (enode->opType != OP_AND || enode->getChild(1)->opType != OP_INT) { + // printf("---isBitAndOne if1 failed---\n"); + return nullptr; + } + auto value = firStrBase(enode->getChild(1)->strVal); + if (value.second != "1") { + // printf("---isBitAndOne if2 failed--- value.second == %s\n", value.second.c_str()); + return nullptr; + } + if (!enode->getChild(0)) { + // printf("---isBitAndOne if3 failed---\n"); + return nullptr; + } + return enode->getChild(0); +} +// (1 << expr) +bool checkPattern1(Node* node) { if (node->isArray() || node->type != NODE_OTHERS || node->assignTree.size() != 1) return false; ENode* root = node->assignTree[0]->getRoot(); ENode* shiftENode = isDshlOne(root); @@ -47,15 +67,235 @@ bool checkPatern1(Node* node) { if (ret) node->status = DEAD_NODE; return ret; } +// ((1<isArray() || node->type != NODE_OTHERS || node->assignTree.size() != 1) { + // printf("---checkPattern2 if1 failed---\n"); + return false; + } + ENode* root = node->assignTree[0]->getRoot(); + ENode* bitAndNode = isBitAndOne(root); + + // ExpTree* tree = new ExpTree(bitAndNode, new ENode(node)); + // printf("---checkPattern2 bitAndNode tree---\n"); + // tree->display(); + // if (pattern == (A & 1)) bitAndNode is A + if (!bitAndNode) { + // printf("---checkPattern2 if2 failed---\n"); + return false; + } + // if A == (1 << expr), shiftNode is expr + // printf("bitAndNode: (opType=OP_DSHL) == %d\n, (child0 opType=OP_INT) == %d child0 value second == %s\n", + // bitAndNode->opType == OP_DSHL, bitAndNode->getChild(0)->opType == OP_INT, firStrBase(bitAndNode->getChild(0)->strVal).second.c_str()); + ENode* shiftNode = nullptr; + if (bitAndNode->opType == OP_DSHL && bitAndNode->getChild(0)->opType == OP_INT && firStrBase(bitAndNode->getChild(0)->strVal).second == "1") { + shiftNode = bitAndNode->getChild(1); + } else { + shiftNode = nullptr; + } + // ExpTree* tree2 = new ExpTree(shiftNode, new ENode(node)); + // printf("---checkPattern2 shiftNode tree---\n"); + // tree2->display(); + if (!shiftNode) { + // printf("---checkPattern2 if3 failed---\n"); + return false; + } + return true; +} + +// A & 1 +bool checkPattern3(Node *node) { + if (node->isArray() || node->type != NODE_OTHERS || node->assignTree.size() != 1) { + return false; + } + ENode* root = node->assignTree[0]->getRoot(); + if (root->opType != OP_AND) { + return false; + } + if (root->getChild(1)->opType != OP_INT) { + return false; + } + auto value = firStrBase(root->getChild(1)->strVal); + if (value.second != "1") { + return false; + } + return true; +} + +void testCheckPattern2() { + // Test case 1: Valid pattern (1 << 5) & 0x1 + // both "1" maybe 0h1 or 0b1 or 0o1 or 1 + { + Node* testNode = new Node(); + testNode->type = NODE_OTHERS; + testNode->width = 1; + + ENode* exprNode = new ENode(OP_INT); + exprNode->strVal = "5"; + exprNode->width = 32; + + ENode* shiftNode = new ENode(OP_DSHL); + shiftNode->width = 32; + ENode* oneNode = new ENode(OP_INT); + oneNode->strVal = "1"; + oneNode->width = 32; + shiftNode->addChild(oneNode); + shiftNode->addChild(exprNode); + + ENode* andNode = new ENode(OP_AND); + andNode->width = 1; + andNode->addChild(shiftNode); + ENode* maskNode = new ENode(OP_INT); + maskNode->strVal = "0h1"; + maskNode->width = 32; + andNode->addChild(maskNode); + + ExpTree* tree = new ExpTree(andNode, new ENode(testNode)); + testNode->assignTree.push_back(tree); + + bool result = checkPattern2(testNode); + Assert(result == true, "testCheckPattern2 case1 failed"); + + delete testNode; + } + + // Test case 2: Invalid pattern - not AND operation + { + Node* testNode = new Node(); + testNode->type = NODE_OTHERS; + testNode->width = 1; + + ENode* exprNode = new ENode(OP_INT); + exprNode->strVal = "5"; + exprNode->width = 32; + + ENode* shiftNode = new ENode(OP_DSHL); + shiftNode->width = 32; + ENode* oneNode = new ENode(OP_INT); + oneNode->strVal = "1"; + oneNode->width = 32; + shiftNode->addChild(oneNode); + shiftNode->addChild(exprNode); + + // Using OR instead of AND + ENode* orNode = new ENode(OP_OR); + orNode->width = 1; + orNode->addChild(shiftNode); + ENode* maskNode = new ENode(OP_INT); + maskNode->strVal = "1"; + maskNode->width = 1; + orNode->addChild(maskNode); + + ExpTree* tree = new ExpTree(orNode, new ENode(testNode)); + testNode->assignTree.push_back(tree); + + bool result = checkPattern2(testNode); + Assert(result == false, "testCheckPattern2 case2 failed"); + + delete testNode; + } + + // Test case 3: Invalid pattern - mask is not 1 + { + Node* testNode = new Node(); + testNode->type = NODE_OTHERS; + testNode->width = 1; + + ENode* exprNode = new ENode(OP_INT); + exprNode->strVal = "5"; + exprNode->width = 32; + + ENode* shiftNode = new ENode(OP_DSHL); + shiftNode->width = 32; + ENode* oneNode = new ENode(OP_INT); + oneNode->strVal = "1"; + oneNode->width = 32; + shiftNode->addChild(oneNode); + shiftNode->addChild(exprNode); + + ENode* andNode = new ENode(OP_AND); + andNode->width = 1; + andNode->addChild(shiftNode); + ENode* maskNode = new ENode(OP_INT); + maskNode->strVal = "2"; // Invalid mask value + maskNode->width = 1; + andNode->addChild(maskNode); + + ExpTree* tree = new ExpTree(andNode, new ENode(testNode)); + testNode->assignTree.push_back(tree); + + bool result = checkPattern2(testNode); + Assert(result == false, "testCheckPattern2 case3 failed"); + + delete testNode; + } + + // Test case 4: Invalid pattern - shift value is not 1 + { + Node* testNode = new Node(); + testNode->type = NODE_OTHERS; + testNode->width = 1; + + ENode* exprNode = new ENode(OP_INT); + exprNode->strVal = "5"; + exprNode->width = 32; + + ENode* shiftNode = new ENode(OP_DSHL); + shiftNode->width = 32; + ENode* oneNode = new ENode(OP_INT); + oneNode->strVal = "2"; // Invalid shift value + oneNode->width = 32; + shiftNode->addChild(oneNode); + shiftNode->addChild(exprNode); + + ENode* andNode = new ENode(OP_AND); + andNode->width = 1; + andNode->addChild(shiftNode); + ENode* maskNode = new ENode(OP_INT); + maskNode->strVal = "1"; + maskNode->width = 1; + andNode->addChild(maskNode); + + ExpTree* tree = new ExpTree(andNode, new ENode(testNode)); + testNode->assignTree.push_back(tree); + + bool result = checkPattern2(testNode); + Assert(result == false, "testCheckPattern2 case4 failed"); + + delete testNode; + } +} void graph::patternDetect() { + testCheckPattern2(); int num1 = 0; + int num2 = 0; + int num3 = 0; + + // check pattern3 for (SuperNode* super : sortedSuper) { for (Node* member : super->member) { - num1 += checkPatern1(member); + num3 += checkPattern3(member); + } + } + + // check pattern2 + for (SuperNode* super : sortedSuper) { + for (Node* member : super->member) { + num2 += checkPattern2(member); + } + } + + + // check pattern1 + for (SuperNode* super : sortedSuper) { + for (Node* member : super->member) { + num1 += checkPattern1(member); } } removeNodesNoConnect(DEAD_NODE); reconnectAll(); - printf("[patternDetect] find %d pattern1\n", num1); -} \ No newline at end of file + printf("[patternDetect] find %d pattern1, %d pattern2((1< Date: Mon, 3 Mar 2025 19:11:38 +0800 Subject: [PATCH 2/2] patternDetect: add pattern4 --- src/.patternDetect.cpp.swp | Bin 0 -> 20480 bytes src/patternDetect.cpp | 287 +++++++++++++++++-------------------- 2 files changed, 131 insertions(+), 156 deletions(-) create mode 100644 src/.patternDetect.cpp.swp diff --git a/src/.patternDetect.cpp.swp b/src/.patternDetect.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..7a2ca767ce4204d91258ed8617fdb4163261df3d GIT binary patch literal 20480 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 #include #include "common.h" +#include /* detect and optimize some specific patterns */ /* behind constantAnalysis */ Node* getLeafNode(bool isArray, ENode* enode); @@ -27,20 +28,48 @@ static bool isBitsOne(ENode* enode) { // else return nullptr static ENode* isBitAndOne(ENode* enode) { if (enode->opType != OP_AND || enode->getChild(1)->opType != OP_INT) { - // printf("---isBitAndOne if1 failed---\n"); return nullptr; } auto value = firStrBase(enode->getChild(1)->strVal); if (value.second != "1") { - // printf("---isBitAndOne if2 failed--- value.second == %s\n", value.second.c_str()); return nullptr; } if (!enode->getChild(0)) { - // printf("---isBitAndOne if3 failed---\n"); return nullptr; } return enode->getChild(0); } + +/* pattern 4: + node expr_lo = cat(expr_A, expr_B) + node expr_hi = cat(expr_C, expr_D) + node _expr_T = cat(expr_hi, expr_lo) + node expr = orr(_expr_T) + optimize: + expr = ( orr(expr_A) | orr(expr_B) | orr(expr_C) | orr(expr_D) ) +*/ +bool checkNestedCat(ENode* enode, std::vector& leafNodes, bool hasCat) { + if (enode->opType == OP_EMPTY && enode->nodePtr) { + Node* refNode = enode->nodePtr; + if (refNode->assignTree.size() == 1) { + return checkNestedCat(refNode->assignTree[0]->getRoot(), leafNodes, hasCat); + } + return false; + } + if (enode->opType == OP_CAT) { + if (!enode->getChild(0) || !enode->getChild(1)) { + return false; + } + hasCat = true; + return checkNestedCat(enode->getChild(0), leafNodes, hasCat) && checkNestedCat(enode->getChild(1), leafNodes, hasCat); + } + if (enode->opType == OP_BITS && hasCat) { + leafNodes.push_back(enode); + return true; + } + return false; +} + // (1 << expr) bool checkPattern1(Node* node) { if (node->isArray() || node->type != NODE_OTHERS || node->assignTree.size() != 1) return false; @@ -70,34 +99,25 @@ bool checkPattern1(Node* node) { // ((1<isArray() || node->type != NODE_OTHERS || node->assignTree.size() != 1) { - // printf("---checkPattern2 if1 failed---\n"); return false; } ENode* root = node->assignTree[0]->getRoot(); ENode* bitAndNode = isBitAndOne(root); - // ExpTree* tree = new ExpTree(bitAndNode, new ENode(node)); - // printf("---checkPattern2 bitAndNode tree---\n"); - // tree->display(); + // if (pattern == (A & 1)) bitAndNode is A if (!bitAndNode) { - // printf("---checkPattern2 if2 failed---\n"); return false; } - // if A == (1 << expr), shiftNode is expr - // printf("bitAndNode: (opType=OP_DSHL) == %d\n, (child0 opType=OP_INT) == %d child0 value second == %s\n", - // bitAndNode->opType == OP_DSHL, bitAndNode->getChild(0)->opType == OP_INT, firStrBase(bitAndNode->getChild(0)->strVal).second.c_str()); + ENode* shiftNode = nullptr; if (bitAndNode->opType == OP_DSHL && bitAndNode->getChild(0)->opType == OP_INT && firStrBase(bitAndNode->getChild(0)->strVal).second == "1") { shiftNode = bitAndNode->getChild(1); } else { shiftNode = nullptr; } - // ExpTree* tree2 = new ExpTree(shiftNode, new ENode(node)); - // printf("---checkPattern2 shiftNode tree---\n"); - // tree2->display(); + if (!shiftNode) { - // printf("---checkPattern2 if3 failed---\n"); return false; } return true; @@ -122,155 +142,110 @@ bool checkPattern3(Node *node) { return true; } -void testCheckPattern2() { - // Test case 1: Valid pattern (1 << 5) & 0x1 - // both "1" maybe 0h1 or 0b1 or 0o1 or 1 - { - Node* testNode = new Node(); - testNode->type = NODE_OTHERS; - testNode->width = 1; - - ENode* exprNode = new ENode(OP_INT); - exprNode->strVal = "5"; - exprNode->width = 32; - - ENode* shiftNode = new ENode(OP_DSHL); - shiftNode->width = 32; - ENode* oneNode = new ENode(OP_INT); - oneNode->strVal = "1"; - oneNode->width = 32; - shiftNode->addChild(oneNode); - shiftNode->addChild(exprNode); - - ENode* andNode = new ENode(OP_AND); - andNode->width = 1; - andNode->addChild(shiftNode); - ENode* maskNode = new ENode(OP_INT); - maskNode->strVal = "0h1"; - maskNode->width = 32; - andNode->addChild(maskNode); - - ExpTree* tree = new ExpTree(andNode, new ENode(testNode)); - testNode->assignTree.push_back(tree); - - bool result = checkPattern2(testNode); - Assert(result == true, "testCheckPattern2 case1 failed"); - - delete testNode; +/* orr (expr), expr = cat(expr_A, expr_B) + * orr(cat(expr_A, expr_B)) + * maybe recursive + */ +bool checkPattern4(Node* node) { + if (node->isArray() || node->type != NODE_OTHERS || node->assignTree.size() != 1) { + return false; } - - // Test case 2: Invalid pattern - not AND operation - { - Node* testNode = new Node(); - testNode->type = NODE_OTHERS; - testNode->width = 1; - - ENode* exprNode = new ENode(OP_INT); - exprNode->strVal = "5"; - exprNode->width = 32; - - ENode* shiftNode = new ENode(OP_DSHL); - shiftNode->width = 32; - ENode* oneNode = new ENode(OP_INT); - oneNode->strVal = "1"; - oneNode->width = 32; - shiftNode->addChild(oneNode); - shiftNode->addChild(exprNode); - - // Using OR instead of AND - ENode* orNode = new ENode(OP_OR); - orNode->width = 1; - orNode->addChild(shiftNode); - ENode* maskNode = new ENode(OP_INT); - maskNode->strVal = "1"; - maskNode->width = 1; - orNode->addChild(maskNode); - - ExpTree* tree = new ExpTree(orNode, new ENode(testNode)); - testNode->assignTree.push_back(tree); - - bool result = checkPattern2(testNode); - Assert(result == false, "testCheckPattern2 case2 failed"); - - delete testNode; + ENode* root = node->assignTree[0]->getRoot(); + if (root->opType != OP_ORR) { + return false; } - - // Test case 3: Invalid pattern - mask is not 1 - { - Node* testNode = new Node(); - testNode->type = NODE_OTHERS; - testNode->width = 1; - - ENode* exprNode = new ENode(OP_INT); - exprNode->strVal = "5"; - exprNode->width = 32; - - ENode* shiftNode = new ENode(OP_DSHL); - shiftNode->width = 32; - ENode* oneNode = new ENode(OP_INT); - oneNode->strVal = "1"; - oneNode->width = 32; - shiftNode->addChild(oneNode); - shiftNode->addChild(exprNode); - - ENode* andNode = new ENode(OP_AND); - andNode->width = 1; - andNode->addChild(shiftNode); - ENode* maskNode = new ENode(OP_INT); - maskNode->strVal = "2"; // Invalid mask value - maskNode->width = 1; - andNode->addChild(maskNode); - - ExpTree* tree = new ExpTree(andNode, new ENode(testNode)); - testNode->assignTree.push_back(tree); - - bool result = checkPattern2(testNode); - Assert(result == false, "testCheckPattern2 case3 failed"); - - delete testNode; + std::vector leafNodes; + if (!root->getChild(0)) { + return false; // never happen } - - // Test case 4: Invalid pattern - shift value is not 1 - { - Node* testNode = new Node(); - testNode->type = NODE_OTHERS; - testNode->width = 1; - - ENode* exprNode = new ENode(OP_INT); - exprNode->strVal = "5"; - exprNode->width = 32; - - ENode* shiftNode = new ENode(OP_DSHL); - shiftNode->width = 32; - ENode* oneNode = new ENode(OP_INT); - oneNode->strVal = "2"; // Invalid shift value - oneNode->width = 32; - shiftNode->addChild(oneNode); - shiftNode->addChild(exprNode); - - ENode* andNode = new ENode(OP_AND); - andNode->width = 1; - andNode->addChild(shiftNode); - ENode* maskNode = new ENode(OP_INT); - maskNode->strVal = "1"; - maskNode->width = 1; - andNode->addChild(maskNode); - - ExpTree* tree = new ExpTree(andNode, new ENode(testNode)); - testNode->assignTree.push_back(tree); - - bool result = checkPattern2(testNode); - Assert(result == false, "testCheckPattern2 case4 failed"); - - delete testNode; + bool res = checkNestedCat(root->getChild(0), leafNodes, false); + if (res && leafNodes.size() > 1) { + ENode* newRoot = new ENode(OP_OR); + newRoot->width = root->width; + newRoot->sign = root->sign; + for (ENode* leaf : leafNodes) { + ENode* orr = new ENode(OP_ORR); + orr->width = 1; + orr->addChild(leaf->dup()); + newRoot->addChild(orr); + } + printf("p4 tree before optimize:\n"); + root->display(); + ExpTree* newTree = new ExpTree(newRoot, new ENode(node)); + node->assignTree.clear(); + node->assignTree.push_back(newTree); + printf("p4 tree after optimize:\n"); + newTree->display(); } + return res; +} + +void testCheckPattern4() { + Node *node = new Node(); + node->type = NODE_OTHERS; + node->assignTree.push_back(new ExpTree(new ENode(OP_ORR))); + ENode *orr = node->assignTree[0]->getRoot(); + orr->addChild(new ENode(OP_CAT)); + ENode* cat = orr->getChild(0); + ENode* bits1 = new ENode(OP_BITS); + bits1->width = 2; + bits1->addVal(0); + bits1->addVal(1); + cat->addChild(bits1); + ENode* bits2 = new ENode(OP_BITS); + bits2->width = 2; + bits2->addVal(0); + bits2->addVal(1); + cat->addChild(bits2); + Assert(checkPattern4(node), "testCheckPattern4 case 1 failed"); + + // Test case for pattern: node B = cat(C, D); node A = orr(B); + Node *nodeB = new Node(); + nodeB->type = NODE_OTHERS; + nodeB->assignTree.push_back(new ExpTree(new ENode(OP_CAT))); + ENode *catB = nodeB->assignTree[0]->getRoot(); + + // Add children C and D to cat node + ENode* enodeC = new ENode(OP_BITS); + enodeC->width = 2; + enodeC->addVal(0); + enodeC->addVal(1); + catB->addChild(enodeC); + + ENode* enodeD = new ENode(OP_BITS); + enodeD->width = 2; + enodeD->addVal(0); + enodeD->addVal(1); + catB->addChild(enodeD); + + // Create node A with orr operation + Node *nodeA = new Node(); + nodeA->type = NODE_OTHERS; + nodeA->assignTree.push_back(new ExpTree(new ENode(OP_ORR))); + ENode *orrA = nodeA->assignTree[0]->getRoot(); + + // Link orr to node B + ENode *refB = new ENode(OP_EMPTY); + refB->nodePtr = nodeB; + orrA->addChild(refB); + + Assert(checkPattern4(nodeA), "testCheckPattern4 case 2 failed"); } void graph::patternDetect() { - testCheckPattern2(); int num1 = 0; int num2 = 0; int num3 = 0; + int num4 = 0; + + //testCheckPattern4(); + + // check pattern4 + for (SuperNode* super : sortedSuper) { + for (Node* member : super->member) { + num4 += checkPattern4(member); + } + } // check pattern3 for (SuperNode* super : sortedSuper) { @@ -287,7 +262,7 @@ void graph::patternDetect() { } - // check pattern1 + // check pattern1, and optimize for (SuperNode* super : sortedSuper) { for (Node* member : super->member) { num1 += checkPattern1(member); @@ -295,7 +270,7 @@ void graph::patternDetect() { } removeNodesNoConnect(DEAD_NODE); reconnectAll(); - printf("[patternDetect] find %d pattern1, %d pattern2((1<