Thanks for pointing out this. I shall do the refactoring.<div><br></div><div>Chris, why do you think this implementation is slower than the version in llvm/Analysis (based on the classical Lengauer-Tarjan algorithm)? My patch was based on this 2001 paper: K. D. Cooper "A Simple, Fast Dominance Algorithm", which actually included an interesting analysis and comparison with the classical Lengauer-Tarjan algorithm. I believe the implementation in core LLVM shall be very stable and efficient. I am just interested in know why choosing this.</div>
<div><br></div><div>--</div><div>Guoping<br><br><div class="gmail_quote">2011/10/24 Ted Kremenek <span dir="ltr"><<a href="mailto:kremenek@apple.com">kremenek@apple.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Good point Chris. I think reusing the existing dominators logic in llvm/Analysis makes good sense. We already implement several graph traits already for the source level CFG.<br>
<br>
Guoping: now that we have this base implementation, including API, in Clang, would you be interested in refactoring it to use the dominators logic in llvm/Analysis. Otherwise, I'll look into refactoring it.<br>
<br>
Sent from my iPad<br>
<br>
On Oct 24, 2011, at 5:33 PM, Chris Lattner <<a href="mailto:clattner@apple.com">clattner@apple.com</a>> wrote:<br>
<br>
><br>
> On Oct 24, 2011, at 5:25 PM, Ted Kremenek wrote:<br>
><br>
>> Author: kremenek<br>
>> Date: Mon Oct 24 19:25:24 2011<br>
>> New Revision: 142885<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=142885&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=142885&view=rev</a><br>
>> Log:<br>
>> Add source-level dominators analysis. Patch by Guoping Long!<br>
><br>
> This reimplements a bunch of code that we already have templates out based on Graph type (see llvm/Analysis/DominatorInternals.h). Why duplicate it? AFAICT, this is also slower than the version in llvm/Analysis.<br>
><br>
> -Chris<br>
><br>
>><br>
>> Added:<br>
>> cfe/trunk/include/clang/Analysis/Analyses/Dominators.h<br>
>> cfe/trunk/lib/Analysis/Dominators.cpp<br>
>> cfe/trunk/test/Analysis/domtest.c<br>
>> Modified:<br>
>> cfe/trunk/lib/Analysis/CMakeLists.txt<br>
>> cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td<br>
>> cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp<br>
>><br>
>> Added: cfe/trunk/include/clang/Analysis/Analyses/Dominators.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/Dominators.h?rev=142885&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/Dominators.h?rev=142885&view=auto</a><br>
>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/Analysis/Analyses/Dominators.h (added)<br>
>> +++ cfe/trunk/include/clang/Analysis/Analyses/Dominators.h Mon Oct 24 19:25:24 2011<br>
>> @@ -0,0 +1,156 @@<br>
>> +//==- Dominators.cpp - Construct the Dominance Tree Given CFG ----*- C++ --*-==//<br>
>> +//<br>
>> +// The LLVM Compiler Infrastructure<br>
>> +//<br>
>> +// This file is distributed under the University of Illinois Open Source<br>
>> +// License. See LICENSE.TXT for details.<br>
>> +//<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +//<br>
>> +// This file implements a simple, fast dominance algorithm for source-level CFGs.<br>
>> +//<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +<br>
>> +#ifndef LLVM_CLANG_DOMINATORS_H<br>
>> +#define LLVM_CLANG_DOMINATORS_H<br>
>> +<br>
>> +#include "clang/Analysis/CFG.h"<br>
>> +#include "clang/Analysis/AnalysisContext.h"<br>
>> +#include "llvm/ADT/DenseMap.h"<br>
>> +<br>
>> +namespace clang {<br>
>> +<br>
>> +class CFG;<br>
>> +class CFGBlock;<br>
>> +<br>
>> +class DominatorTree : public ManagedAnalysis {<br>
>> + typedef llvm::DenseMap<const CFGBlock *, CFGBlock*> CFGBlockMapTy;<br>
>> +<br>
>> +public:<br>
>> + DominatorTree(AnalysisDeclContext &ac)<br>
>> + : AC(ac) {};<br>
>> +<br>
>> + virtual ~DominatorTree();<br>
>> +<br>
>> + /// Return the immediate dominator node given a CFGBlock.<br>
>> + /// For entry block, the dominator is itself.<br>
>> + /// This is the same as using operator[] on this class.<br>
>> + CFGBlock *getNode(const CFGBlock *B) const;<br>
>> +<br>
>> + /// This returns the Entry Block for the given CFG<br>
>> + CFGBlock *getRootNode() { return RootNode; }<br>
>> + const CFGBlock *getRootNode() const { return RootNode; }<br>
>> +<br>
>> + /// Returns true iff A dominates B and A != B.<br>
>> + /// Note that this is not a constant time operation.<br>
>> + bool properlyDominates(const CFGBlock *A, const CFGBlock *B) const;<br>
>> +<br>
>> + /// Returns true iff A dominates B.<br>
>> + bool dominates(const CFGBlock *A, const CFGBlock *B) const;<br>
>> +<br>
>> + /// Find nearest common dominator for blocks A and B.<br>
>> + /// Common dominator always exists, ex: entry block.<br>
>> + const CFGBlock *findNearestCommonDominator(const CFGBlock *A,<br>
>> + const CFGBlock *B) const;<br>
>> +<br>
>> + /// Constructs immediate dominator tree for a given CFG based on the algorithm<br>
>> + /// described in this paper:<br>
>> + ///<br>
>> + /// A Simple, Fast Dominance Algorithm<br>
>> + /// Keith D. Cooper, Timothy J. Harvey and Ken Kennedy<br>
>> + /// Software-Practice and Expreience, 2001;4:1-10.<br>
>> + ///<br>
>> + /// This implementation is simple and runs faster in practice than the classis<br>
>> + /// Lengauer-Tarjan algorithm. For detailed discussions, refer to the paper.<br>
>> + void BuildDominatorTree();<br>
>> +<br>
>> + /// Dump the immediate dominance tree<br>
>> + void dump();<br>
>> +<br>
>> +private:<br>
>> + AnalysisDeclContext &AC;<br>
>> + CFGBlock *RootNode;<br>
>> + CFGBlockMapTy IDoms;<br>
>> +};<br>
>> +<br>
>> +} // end namespace clang<br>
>> +<br>
>> +#endif<br>
>> +//==- Dominators.cpp - Construct the Dominance Tree Given CFG ----*- C++ --*-==//<br>
>> +//<br>
>> +// The LLVM Compiler Infrastructure<br>
>> +//<br>
>> +// This file is distributed under the University of Illinois Open Source<br>
>> +// License. See LICENSE.TXT for details.<br>
>> +//<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +//<br>
>> +// This file implements a simple, fast dominance algorithm for source-level CFGs.<br>
>> +//<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +<br>
>> +#ifndef LLVM_CLANG_DOMINATORS_H<br>
>> +#define LLVM_CLANG_DOMINATORS_H<br>
>> +<br>
>> +#include "clang/Analysis/CFG.h"<br>
>> +#include "clang/Analysis/AnalysisDeclContext.h"<br>
>> +#include "llvm/ADT/DenseMap.h"<br>
>> +<br>
>> +namespace clang {<br>
>> +<br>
>> +class CFG;<br>
>> +class CFGBlock;<br>
>> +<br>
>> +class DominatorTree : public ManagedAnalysis {<br>
>> + typedef llvm::DenseMap<const CFGBlock *, CFGBlock*> CFGBlockMapTy;<br>
>> +<br>
>> +public:<br>
>> + DominatorTree(AnalysisDeclContext &ac)<br>
>> + : AC(ac) {};<br>
>> +<br>
>> + virtual ~DominatorTree();<br>
>> +<br>
>> + /// Return the immediate dominator node given a CFGBlock.<br>
>> + /// For entry block, the dominator is itself.<br>
>> + /// This is the same as using operator[] on this class.<br>
>> + CFGBlock *getNode(const CFGBlock *B) const;<br>
>> +<br>
>> + /// This returns the Entry Block for the given CFG<br>
>> + CFGBlock *getRootNode() { return RootNode; }<br>
>> + const CFGBlock *getRootNode() const { return RootNode; }<br>
>> +<br>
>> + /// Returns true iff A dominates B and A != B.<br>
>> + /// Note that this is not a constant time operation.<br>
>> + bool properlyDominates(const CFGBlock *A, const CFGBlock *B) const;<br>
>> +<br>
>> + /// Returns true iff A dominates B.<br>
>> + bool dominates(const CFGBlock *A, const CFGBlock *B) const;<br>
>> +<br>
>> + /// Find nearest common dominator for blocks A and B.<br>
>> + /// Common dominator always exists, ex: entry block.<br>
>> + const CFGBlock *findNearestCommonDominator(const CFGBlock *A,<br>
>> + const CFGBlock *B) const;<br>
>> +<br>
>> + /// Constructs immediate dominator tree for a given CFG based on the algorithm<br>
>> + /// described in this paper:<br>
>> + ///<br>
>> + /// A Simple, Fast Dominance Algorithm<br>
>> + /// Keith D. Cooper, Timothy J. Harvey and Ken Kennedy<br>
>> + /// Software-Practice and Expreience, 2001;4:1-10.<br>
>> + ///<br>
>> + /// This implementation is simple and runs faster in practice than the classis<br>
>> + /// Lengauer-Tarjan algorithm. For detailed discussions, refer to the paper.<br>
>> + void BuildDominatorTree();<br>
>> +<br>
>> + /// Dump the immediate dominance tree<br>
>> + void dump();<br>
>> +<br>
>> +private:<br>
>> + AnalysisDeclContext &AC;<br>
>> + CFGBlock *RootNode;<br>
>> + CFGBlockMapTy IDoms;<br>
>> +};<br>
>> +<br>
>> +} // end namespace clang<br>
>> +<br>
>> +#endif<br>
>><br>
>> Modified: cfe/trunk/lib/Analysis/CMakeLists.txt<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=142885&r1=142884&r2=142885&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=142885&r1=142884&r2=142885&view=diff</a><br>
>> ==============================================================================<br>
>> --- cfe/trunk/lib/Analysis/CMakeLists.txt (original)<br>
>> +++ cfe/trunk/lib/Analysis/CMakeLists.txt Mon Oct 24 19:25:24 2011<br>
>> @@ -6,6 +6,7 @@<br>
>> CFGReachabilityAnalysis.cpp<br>
>> CFGStmtMap.cpp<br>
>> CocoaConventions.cpp<br>
>> + Dominators.cpp<br>
>> FormatString.cpp<br>
>> LiveVariables.cpp<br>
>> PostOrderCFGView.cpp<br>
>><br>
>> Added: cfe/trunk/lib/Analysis/Dominators.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Dominators.cpp?rev=142885&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Dominators.cpp?rev=142885&view=auto</a><br>
>> ==============================================================================<br>
>> --- cfe/trunk/lib/Analysis/Dominators.cpp (added)<br>
>> +++ cfe/trunk/lib/Analysis/Dominators.cpp Mon Oct 24 19:25:24 2011<br>
>> @@ -0,0 +1,160 @@<br>
>> +//==- Dominators.cpp - Construct the Dominance Tree Given CFG ----*- C++ --*-==//<br>
>> +//<br>
>> +// The LLVM Compiler Infrastructure<br>
>> +//<br>
>> +// This file is distributed under the University of Illinois Open Source<br>
>> +// License. See LICENSE.TXT for details.<br>
>> +//<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +//<br>
>> +// This file implements a simple, fast dominance algorithm for source-level CFGs.<br>
>> +//<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +<br>
>> +#include "clang/Analysis/Analyses/Dominators.h"<br>
>> +#include "clang/Analysis/CFG.h"<br>
>> +#include "clang/Analysis/AnalysisContext.h"<br>
>> +#include "clang/Analysis/Analyses/PostOrderCFGView.h"<br>
>> +<br>
>> +using namespace clang;<br>
>> +<br>
>> +DominatorTree::~DominatorTree() {<br>
>> + IDoms.clear();<br>
>> + RootNode = 0;<br>
>> +}<br>
>> +<br>
>> +CFGBlock * DominatorTree::getNode(const CFGBlock *B) const {<br>
>> + CFGBlockMapTy::const_iterator I = IDoms.find(B);<br>
>> + return I != IDoms.end() ? I->second : 0;<br>
>> +}<br>
>> +<br>
>> +bool DominatorTree::properlyDominates(const CFGBlock *A,<br>
>> + const CFGBlock *B) const {<br>
>> + if (0 == A || 0 == B || A == B)<br>
>> + return false;<br>
>> +<br>
>> + // The EntryBlock dominates every other block.<br>
>> + if (A == RootNode)<br>
>> + return true;<br>
>> +<br>
>> + // Note: The dominator of the EntryBlock is itself.<br>
>> + CFGBlock *IDom = getNode(B);<br>
>> + while (IDom != A && IDom != RootNode)<br>
>> + IDom = getNode(IDom);<br>
>> +<br>
>> + return IDom != RootNode;<br>
>> +}<br>
>> +<br>
>> +bool DominatorTree::dominates(const CFGBlock *A,<br>
>> + const CFGBlock *B) const {<br>
>> + if (A == B)<br>
>> + return true;<br>
>> +<br>
>> + return properlyDominates(A, B);<br>
>> +}<br>
>> +<br>
>> +const CFGBlock * DominatorTree::findNearestCommonDominator<br>
>> + (const CFGBlock *A, const CFGBlock *B) const {<br>
>> + //If A dominates B, then A is the nearest common dominator<br>
>> + if (dominates(A, B))<br>
>> + return A;<br>
>> +<br>
>> + //If B dominates A, then B is the nearest common dominator<br>
>> + if (dominates(B, A))<br>
>> + return B;<br>
>> +<br>
>> + //Collect all A's dominators<br>
>> + llvm::SmallPtrSet<CFGBlock *, 16> ADoms;<br>
>> + ADoms.insert(RootNode);<br>
>> + CFGBlock *ADom = getNode(A);<br>
>> + while (ADom != RootNode) {<br>
>> + ADoms.insert(ADom);<br>
>> + ADom = getNode(ADom);<br>
>> + }<br>
>> +<br>
>> + //Check all B's dominators against ADoms<br>
>> + CFGBlock *BDom = getNode(B);<br>
>> + while (BDom != RootNode){<br>
>> + if (ADoms.count(BDom) != 0)<br>
>> + return BDom;<br>
>> +<br>
>> + BDom = getNode(BDom);<br>
>> + }<br>
>> +<br>
>> + //The RootNode dominates every other node<br>
>> + return RootNode;<br>
>> +}<br>
>> +<br>
>> +/// Constructs immediate dominator tree for a given CFG based on the algorithm<br>
>> +/// described in this paper:<br>
>> +///<br>
>> +/// A Simple, Fast Dominance Algorithm<br>
>> +/// Keith D. Cooper, Timothy J. Harvey and Ken Kennedy<br>
>> +/// Software-Practice and Expreience, 2001;4:1-10.<br>
>> +///<br>
>> +/// This implementation is simple and runs faster in practice than the classis<br>
>> +/// Lengauer-Tarjan algorithm. For detailed discussions, refer to the paper.<br>
>> +void DominatorTree::BuildDominatorTree() {<br>
>> + CFG *cfg = AC.getCFG();<br>
>> + CFGBlock *EntryBlk = &cfg->getEntry();<br>
>> +<br>
>> + //Sort all CFGBlocks in reverse order<br>
>> + PostOrderCFGView *rpocfg = AC.getAnalysis<PostOrderCFGView>();<br>
>> +<br>
>> + //Set the root of the dominance tree<br>
>> + RootNode = EntryBlk;<br>
>> +<br>
>> + //Compute the immediate dominator for each CFGBlock<br>
>> + IDoms[EntryBlk] = EntryBlk;<br>
>> + bool changed = true;<br>
>> + while (changed){<br>
>> + changed = false;<br>
>> +<br>
>> + for (PostOrderCFGView::iterator I = rpocfg->begin(),<br>
>> + E = rpocfg->end(); I != E; ++I){<br>
>> + if (EntryBlk == *I)<br>
>> + continue;<br>
>> + if (const CFGBlock *B = *I) {<br>
>> + //Compute immediate dominance information for CFGBlock B<br>
>> + CFGBlock *IDom = 0;<br>
>> + for (CFGBlock::const_pred_iterator J = B->pred_begin(),<br>
>> + K = B->pred_end(); J != K; ++J)<br>
>> + if( CFGBlock *P = *J) {<br>
>> + if (IDoms.find(P) == IDoms.end())<br>
>> + continue;<br>
>> + if (!IDom)<br>
>> + IDom = P;<br>
>> + else {<br>
>> + //intersect IDom and P<br>
>> + CFGBlock *B1 = IDom, *B2 = P;<br>
>> + while (B1 != B2) {<br>
>> + while ((rpocfg->getComparator())(B2,B1))<br>
>> + B1 = IDoms[B1];<br>
>> + while ((rpocfg->getComparator())(B1,B2))<br>
>> + B2 = IDoms[B2];<br>
>> + }<br>
>> + IDom = B1;<br>
>> + }<br>
>> + }<br>
>> + if (IDoms[B] != IDom) {<br>
>> + IDoms[B] = IDom;<br>
>> + changed = true;<br>
>> + }<br>
>> + }<br>
>> + }<br>
>> + }//while<br>
>> +}<br>
>> +<br>
>> +void DominatorTree::dump() {<br>
>> + CFG *cfg = AC.getCFG();<br>
>> +<br>
>> + llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";<br>
>> + for (CFG::const_iterator I = cfg->begin(),<br>
>> + E = cfg->end(); I != E; ++I) {<br>
>> + assert(IDoms[(*I)] &&<br>
>> + "Failed to find the immediate dominator for all CFG blocks.");<br>
>> + llvm::errs() << "(" << (*I)->getBlockID()<br>
>> + << "," << IDoms[(*I)]->getBlockID() << ")\n";<br>
>> + }<br>
>> +}<br>
>> +<br>
>><br>
>> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td?rev=142885&r1=142884&r2=142885&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td?rev=142885&r1=142884&r2=142885&view=diff</a><br>
>> ==============================================================================<br>
>> --- cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td (original)<br>
>> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td Mon Oct 24 19:25:24 2011<br>
>> @@ -359,6 +359,10 @@<br>
>><br>
>> let ParentPackage = Debug in {<br>
>><br>
>> +def DominatorsTreeDumper : Checker<"DumpDominators">,<br>
>> + HelpText<"Print the dominance tree for a given CFG">,<br>
>> + DescFile<"DebugCheckers.cpp">;<br>
>> +<br>
>> def LiveVariablesDumper : Checker<"DumpLiveVars">,<br>
>> HelpText<"Print results of live variable analysis">,<br>
>> DescFile<"DebugCheckers.cpp">;<br>
>><br>
>> Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp?rev=142885&r1=142884&r2=142885&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp?rev=142885&r1=142884&r2=142885&view=diff</a><br>
>> ==============================================================================<br>
>> --- cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp (original)<br>
>> +++ cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp Mon Oct 24 19:25:24 2011<br>
>> @@ -15,11 +15,34 @@<br>
>> #include "clang/StaticAnalyzer/Core/Checker.h"<br>
>> #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"<br>
>> #include "clang/Analysis/Analyses/LiveVariables.h"<br>
>> +#include "clang/Analysis/Analyses/Dominators.h"<br>
>><br>
>> using namespace clang;<br>
>> using namespace ento;<br>
>><br>
>> //===----------------------------------------------------------------------===//<br>
>> +// DominatorsTreeDumper<br>
>> +//===----------------------------------------------------------------------===//<br>
>> +<br>
>> +namespace {<br>
>> +class DominatorsTreeDumper : public Checker<check::ASTCodeBody> {<br>
>> +public:<br>
>> + void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,<br>
>> + BugReporter &BR) const {<br>
>> + if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {<br>
>> + DominatorTree dom(*AC);<br>
>> + dom.BuildDominatorTree();<br>
>> + dom.dump();<br>
>> + }<br>
>> + }<br>
>> +};<br>
>> +}<br>
>> +<br>
>> +void ento::registerDominatorsTreeDumper(CheckerManager &mgr) {<br>
>> + mgr.registerChecker<DominatorsTreeDumper>();<br>
>> +}<br>
>> +<br>
>> +//===----------------------------------------------------------------------===//<br>
>> // LiveVariablesDumper<br>
>> //===----------------------------------------------------------------------===//<br>
>><br>
>><br>
>> Added: cfe/trunk/test/Analysis/domtest.c<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/domtest.c?rev=142885&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/domtest.c?rev=142885&view=auto</a><br>
>> ==============================================================================<br>
>> --- cfe/trunk/test/Analysis/domtest.c (added)<br>
>> +++ cfe/trunk/test/Analysis/domtest.c Mon Oct 24 19:25:24 2011<br>
>> @@ -0,0 +1,165 @@<br>
>> +// RUN: %clang -cc1 -analyze -analyzer-checker=debug.DumpDominators %s 2>&1 | FileCheck %s<br>
>> +<br>
>> +// Test the DominatorsTree implementation with various control flows<br>
>> +int test1()<br>
>> +{<br>
>> + int x = 6;<br>
>> + int y = x/2;<br>
>> + int z;<br>
>> +<br>
>> + while(y > 0) {<br>
>> + if(y < x) {<br>
>> + x = x/y;<br>
>> + y = y-1;<br>
>> + }else{<br>
>> + z = x - y;<br>
>> + }<br>
>> + x = x - 1;<br>
>> + x = x - 1;<br>
>> + }<br>
>> + z = x+y;<br>
>> + z = 3;<br>
>> + return 0;<br>
>> +}<br>
>> +<br>
>> +// CHECK: Immediate dominance tree (Node#,IDom#):<br>
>> +// CHECK: (0,1)<br>
>> +// CHECK: (1,2)<br>
>> +// CHECK: (2,8)<br>
>> +// CHECK: (3,4)<br>
>> +// CHECK: (4,7)<br>
>> +// CHECK: (5,7)<br>
>> +// CHECK: (6,7)<br>
>> +// CHECK: (7,2)<br>
>> +// CHECK: (8,9)<br>
>> +// CHECK: (9,9)<br>
>> +<br>
>> +int test2()<br>
>> +{<br>
>> + int x,y,z;<br>
>> +<br>
>> + x = 10; y = 100;<br>
>> + if(x > 0){<br>
>> + y = 1;<br>
>> + }else{<br>
>> + while(x<=0){<br>
>> + x++;<br>
>> + y++;<br>
>> + }<br>
>> + }<br>
>> + z = y;<br>
>> +<br>
>> + return 0;<br>
>> +}<br>
>> +<br>
>> +// CHECK: Immediate dominance tree (Node#,IDom#):<br>
>> +// CHECK: (0,1)<br>
>> +// CHECK: (1,6)<br>
>> +// CHECK: (2,6)<br>
>> +// CHECK: (3,4)<br>
>> +// CHECK: (4,2)<br>
>> +// CHECK: (5,6)<br>
>> +// CHECK: (6,7)<br>
>> +// CHECK: (7,7)<br>
>> +<br>
>> +int test3()<br>
>> +{<br>
>> + int x,y,z;<br>
>> +<br>
>> + x = y = z = 1;<br>
>> + if(x>0) {<br>
>> + while(x>=0){<br>
>> + while(y>=x) {<br>
>> + x = x-1;<br>
>> + y = y/2;<br>
>> + }<br>
>> + }<br>
>> + }<br>
>> + z = y;<br>
>> +<br>
>> + return 0;<br>
>> +}<br>
>> +<br>
>> +// CHECK: Immediate dominance tree (Node#,IDom#):<br>
>> +// CHECK: (0,1)<br>
>> +// CHECK: (1,7)<br>
>> +// CHECK: (2,7)<br>
>> +// CHECK: (3,4)<br>
>> +// CHECK: (4,2)<br>
>> +// CHECK: (5,6)<br>
>> +// CHECK: (6,4)<br>
>> +// CHECK: (7,8)<br>
>> +// CHECK: (8,8)<br>
>> +<br>
>> +int test4()<br>
>> +{<br>
>> + int y = 3;<br>
>> + while(y > 0) {<br>
>> + if(y < 3) {<br>
>> + while(y>0)<br>
>> + y ++;<br>
>> + }else{<br>
>> + while(y<10)<br>
>> + y ++;<br>
>> + }<br>
>> + }<br>
>> + return 0;<br>
>> +}<br>
>> +<br>
>> +// CHECK: Immediate dominance tree (Node#,IDom#):<br>
>> +// CHECK: (0,1)<br>
>> +// CHECK: (1,2)<br>
>> +// CHECK: (2,11)<br>
>> +// CHECK: (3,10)<br>
>> +// CHECK: (4,10)<br>
>> +// CHECK: (5,6)<br>
>> +// CHECK: (6,4)<br>
>> +// CHECK: (7,10)<br>
>> +// CHECK: (8,9)<br>
>> +// CHECK: (9,7)<br>
>> +// CHECK: (10,2)<br>
>> +// CHECK: (11,12)<br>
>> +// CHECK: (12,12)<br>
>> +<br>
>> +int test5()<br>
>> +{<br>
>> + int x,y,z,a,b,c;<br>
>> + x = 1;<br>
>> + y = 2;<br>
>> + z = 3;<br>
>> + a = 4;<br>
>> + b = 5;<br>
>> + c = 6;<br>
>> + if ( x < 10 ) {<br>
>> + if ( y < 10 ) {<br>
>> + if ( z < 10 ) {<br>
>> + x = 4;<br>
>> + } else {<br>
>> + x = 5;<br>
>> + }<br>
>> + a = 10;<br>
>> + } else {<br>
>> + x = 6;<br>
>> + }<br>
>> + b = 10;<br>
>> + } else {<br>
>> + x = 7;<br>
>> + }<br>
>> + c = 11;<br>
>> + return 0;<br>
>> +}<br>
>> +<br>
>> +// CHECK: Immediate dominance tree (Node#,IDom#):<br>
>> +// CHECK: (0,1)<br>
>> +// CHECK: (1,10)<br>
>> +// CHECK: (2,10)<br>
>> +// CHECK: (3,9)<br>
>> +// CHECK: (4,9)<br>
>> +// CHECK: (5,8)<br>
>> +// CHECK: (6,8)<br>
>> +// CHECK: (7,8)<br>
>> +// CHECK: (8,9)<br>
>> +// CHECK: (9,10)<br>
>> +// CHECK: (10,11)<br>
>> +// CHECK: (11,11)<br>
>> +<br>
>><br>
>><br>
>> _______________________________________________<br>
>> cfe-commits mailing list<br>
>> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
><br>
</blockquote></div><br></div>