Author: resistor Date: Tue Jul 3 13:37:08 2007 New Revision: 37856 URL: http://llvm.org/viewvc/llvm-project?rev=37856&view=rev Log: Add support for performing GVNPRE on cast instructions, and add a testcase for this.
Added: llvm/trunk/test/Transforms/GVNPRE/cast.ll Modified: llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp?rev=37856&r1=37855&r2=37856&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVNPRE.cpp Tue Jul 3 13:37:08 2007 @@ -629,8 +629,41 @@ if (V == 0) return 0; + // Unary Operations + if (isa<CastInst>(V)) { + User* U = cast<User>(V); + + Value* newOp1 = 0; + if (isa<Instruction>(U->getOperand(0))) + newOp1 = phi_translate(U->getOperand(0), pred, succ); + else + newOp1 = U->getOperand(0); + + if (newOp1 == 0) + return 0; + + if (newOp1 != U->getOperand(0)) { + Instruction* newVal = 0; + if (CastInst* C = dyn_cast<CastInst>(U)) + newVal = CastInst::create(C->getOpcode(), + newOp1, C->getType(), + C->getName()+".expr"); + + uint32_t v = VN.lookup_or_add(newVal); + + Value* leader = find_leader(availableOut[pred], v); + if (leader == 0) { + createdExpressions.push_back(newVal); + return newVal; + } else { + VN.erase(newVal); + delete newVal; + return leader; + } + } + // Binary Operations - if (isa<BinaryOperator>(V) || isa<CmpInst>(V) || + } if (isa<BinaryOperator>(V) || isa<CmpInst>(V) || isa<ExtractElementInst>(V)) { User* U = cast<User>(V); @@ -783,8 +816,22 @@ for (unsigned i = 0; i < worklist.size(); ++i) { Value* v = worklist[i]; + // Handle unary ops + if (isa<CastInst>(v)) { + User* U = cast<User>(v); + + bool lhsValid = !isa<Instruction>(U->getOperand(0)); + lhsValid |= presentInSet.test(VN.lookup(U->getOperand(0))); + if (lhsValid) + lhsValid = !dependsOnInvoke(U->getOperand(0)); + + if (!lhsValid) { + set.erase(U); + presentInSet.flip(VN.lookup(U)); + } + // Handle binary ops - if (isa<BinaryOperator>(v) || isa<CmpInst>(v) || + } else if (isa<BinaryOperator>(v) || isa<CmpInst>(v) || isa<ExtractElementInst>(v)) { User* U = cast<User>(v); @@ -843,9 +890,23 @@ while (!stack.empty()) { Value* e = stack.back(); - + + // Handle unary ops + if (isa<CastInst>(e)) { + User* U = cast<User>(e); + Value* l = find_leader(set, VN.lookup(U->getOperand(0))); + + if (l != 0 && isa<Instruction>(l) && + visited.count(l) == 0) + stack.push_back(l); + else { + vec.push_back(e); + visited.insert(e); + stack.pop_back(); + } + // Handle binary ops - if (isa<BinaryOperator>(e) || isa<CmpInst>(e) || + } else if (isa<BinaryOperator>(e) || isa<CmpInst>(e) || isa<ExtractElementInst>(e)) { User* U = cast<User>(e); Value* l = find_leader(set, VN.lookup(U->getOperand(0))); @@ -935,7 +996,8 @@ if (isa<BinaryOperator>(BI) || isa<CmpInst>(BI) || isa<ShuffleVectorInst>(BI) || isa<InsertElementInst>(BI) || - isa<ExtractElementInst>(BI) || isa<SelectInst>(BI)) { + isa<ExtractElementInst>(BI) || isa<SelectInst>(BI) || + isa<CastInst>(BI)) { Value *leader = find_leader(availableOut[BB], VN.lookup(BI)); if (leader != 0) @@ -990,7 +1052,27 @@ availNumbers.resize(VN.size()); currPhis.insert(p); + + // Handle unary ops + } else if (isa<CastInst>(I)) { + User* U = cast<User>(I); + Value* leftValue = U->getOperand(0); + + unsigned num = VN.lookup_or_add(U); + expNumbers.resize(VN.size()); + availNumbers.resize(VN.size()); + + if (isa<Instruction>(leftValue)) + if (!expNumbers.test(VN.lookup(leftValue))) { + currExps.insert(leftValue); + expNumbers.set(VN.lookup(leftValue)); + } + if (!expNumbers.test(VN.lookup(U))) { + currExps.insert(U); + expNumbers.set(num); + } + // Handle binary ops } else if (isa<BinaryOperator>(I) || isa<CmpInst>(I) || isa<ExtractElementInst>(I)) { @@ -1266,21 +1348,31 @@ isa<ShuffleVectorInst>(U->getOperand(0)) || isa<ExtractElementInst>(U->getOperand(0)) || isa<InsertElementInst>(U->getOperand(0)) || - isa<SelectInst>(U->getOperand(0))) + isa<SelectInst>(U->getOperand(0)) || + isa<CastInst>(U->getOperand(0))) s1 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(0))); else s1 = U->getOperand(0); Value* s2 = 0; - if (isa<BinaryOperator>(U->getOperand(1)) || - isa<CmpInst>(U->getOperand(1)) || - isa<ShuffleVectorInst>(U->getOperand(1)) || - isa<ExtractElementInst>(U->getOperand(1)) || - isa<InsertElementInst>(U->getOperand(1)) || - isa<SelectInst>(U->getOperand(1))) - s2 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(1))); - else - s2 = U->getOperand(1); + + if (isa<BinaryOperator>(U) || + isa<CmpInst>(U) || + isa<ShuffleVectorInst>(U) || + isa<ExtractElementInst>(U) || + isa<InsertElementInst>(U) || + isa<SelectInst>(U)) + if (isa<BinaryOperator>(U->getOperand(1)) || + isa<CmpInst>(U->getOperand(1)) || + isa<ShuffleVectorInst>(U->getOperand(1)) || + isa<ExtractElementInst>(U->getOperand(1)) || + isa<InsertElementInst>(U->getOperand(1)) || + isa<SelectInst>(U->getOperand(1)) || + isa<CastInst>(U->getOperand(1))) { + s2 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(1))); + } else { + s2 = U->getOperand(1); + } // Ternary Operators Value* s3 = 0; @@ -1292,10 +1384,12 @@ isa<ShuffleVectorInst>(U->getOperand(2)) || isa<ExtractElementInst>(U->getOperand(2)) || isa<InsertElementInst>(U->getOperand(2)) || - isa<SelectInst>(U->getOperand(2))) + isa<SelectInst>(U->getOperand(2)) || + isa<CastInst>(U->getOperand(2))) { s3 = find_leader(availableOut[*PI], VN.lookup(U->getOperand(2))); - else + } else { s3 = U->getOperand(2); + } Value* newVal = 0; if (BinaryOperator* BO = dyn_cast<BinaryOperator>(U)) @@ -1319,6 +1413,10 @@ newVal = new SelectInst(S->getCondition(), S->getTrueValue(), S->getFalseValue(), S->getName()+".gvnpre", (*PI)->getTerminator()); + else if (CastInst* C = dyn_cast<CastInst>(U)) + newVal = CastInst::create(C->getOpcode(), s1, C->getType(), + C->getName()+".gvnpre", + (*PI)->getTerminator()); VN.add(newVal, VN.lookup(U)); @@ -1365,7 +1463,7 @@ if (isa<BinaryOperator>(e) || isa<CmpInst>(e) || isa<ExtractElementInst>(e) || isa<InsertElementInst>(e) || - isa<ShuffleVectorInst>(e) || isa<SelectInst>(e)) { + isa<ShuffleVectorInst>(e) || isa<SelectInst>(e) || isa<CastInst>(e)) { if (find_leader(availableOut[D->getIDom()->getBlock()], VN.lookup(e)) != 0) continue; Added: llvm/trunk/test/Transforms/GVNPRE/cast.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVNPRE/cast.ll?rev=37856&view=auto ============================================================================== --- llvm/trunk/test/Transforms/GVNPRE/cast.ll (added) +++ llvm/trunk/test/Transforms/GVNPRE/cast.ll Tue Jul 3 13:37:08 2007 @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | opt -gvnpre | llvm-dis | grep b.gvnpre + +define i32 @extract() { +entry: ; preds = %cond_false, %entry + br i1 true, label %cond_true, label %cond_false + +cond_true: + br label %end + +cond_false: + %a = sext i16 0 to i32 + br label %end + +end: + %b = sext i16 0 to i32 + ret i32 %b +} _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits