00001 #include <SectHeader.h>
00002 #include <Instruction.h>
00003 #include <RawSection.h>
00004 #include <SymbolTable.h>
00005 #include <DemangleWrapper.h>
00006 #include <Instruction.h>
00007 #include <Function.h>
00008 #include <Iterator.h>
00009 #include <XCoffFile.h>
00010 #include <BitSet.h>
00011 #include <BinaryFile.h>
00012 #include <Loop.h>
00013 #include <Stack.h>
00014 #include <LinkedList.h>
00015 #include <LengauerTarjan.h>
00016
00017 void LengauerTarjan::depthFirstSearch(uint32_t vertexV,uint32_t* dfsNo){
00018
00019 semi[vertexV] = ++(*dfsNo);
00020 vertex[*dfsNo] = vertexV;
00021
00022 label[vertexV] = vertexV;
00023 ancestor[vertexV] = 0;
00024 child[vertexV] = 0;
00025 size[vertexV] = 1;
00026
00027 BasicBlock* bb = locToBasicBlock[vertexV];
00028
00029 PRINT_DEBUG("Mark %d with %d\n",bb->getIndex(),*dfsNo);
00030
00031 uint32_t numOfTargets = bb->getNumOfTargets();
00032 for(uint32_t i=0;i<numOfTargets;i++){
00033 BasicBlock* target = bb->getTargetBlock(i);
00034 uint32_t vertexW = basicBlockToLoc[target->getIndex()];
00035 if(semi[vertexW] == 0){
00036 parent[vertexW] = vertexV;
00037 depthFirstSearch(vertexW,dfsNo);
00038 }
00039 }
00040 ASSERT(!bb->isNoPath());
00041
00042 #if 0
00043 LinkedList<uint32_t> searchStack;
00044 searchStack.insert(vertexV);
00045
00046 while(!searchStack.empty()){
00047
00048 vertexV = searchStack.shift();
00049
00050 if(semi[vertexV] != 0){
00051 continue;
00052 }
00053
00054 semi[vertexV] = ++(*dfsNo);
00055 vertex[*dfsNo] = vertexV;
00056
00057 label[vertexV] = vertexV;
00058 ancestor[vertexV] = 0;
00059 child[vertexV] = 0;
00060 size[vertexV] = 1;
00061
00062 BasicBlock* bb = locToBasicBlock[vertexV];
00063 ASSERT(!bb->isNoPath());
00064 uint32_t numOfTargets = bb->getNumOfTargets();
00065
00066 for(uint32_t i=0;i<numOfTargets;i++){
00067 BasicBlock* target = bb->getTargetBlock(i);
00068 uint32_t vertexW = basicBlockToLoc[target->getIndex()];
00069 if(semi[vertexW] == 0){
00070 parent[vertexW] = vertexV;
00071 searchStack.insert(vertexW);
00072 }
00073 }
00074 PRINT_DEBUG("Mark %d with %d\n",bb->getIndex(),*dfsNo);
00075 ASSERT(!bb->isNoPath());
00076 }
00077 #endif
00078 }
00079
00080 void LengauerTarjan::COMPRESS(uint32_t vertexV){
00081 if(ancestor[ancestor[vertexV]] != 0){
00082 COMPRESS(ancestor[vertexV]);
00083 if(semi[label[ancestor[vertexV]]] < semi[label[vertexV]]){
00084 label[vertexV] = label[ancestor[vertexV]];
00085 }
00086 ancestor[vertexV] = ancestor[ancestor[vertexV]];
00087 }
00088 }
00089
00090 uint32_t LengauerTarjan::EVAL(uint32_t vertexV){
00091 if(ancestor[vertexV] == 0){
00092 return label[vertexV];
00093 }
00094 COMPRESS(vertexV);
00095 if(semi[label[ancestor[vertexV]]] >= semi[label[vertexV]]){
00096 return label[vertexV];
00097 }
00098 return label[ancestor[vertexV]];
00099 }
00100
00101 void LengauerTarjan::LINK(uint32_t vertexV,uint32_t vertexW){
00102 uint32_t vertexS = vertexW;
00103 while(semi[label[vertexW]] < semi[label[child[vertexS]]]){
00104 if((size[vertexS]+size[child[child[vertexS]]]) >= (2*size[child[vertexS]])){
00105 ancestor[child[vertexS]] = vertexS;
00106 child[vertexS] = child[child[vertexS]];
00107 }
00108 else{
00109 size[child[vertexS]] = size[vertexS];
00110 ancestor[vertexS] = child[vertexS];
00111 vertexS = child[vertexS];
00112 }
00113 }
00114 label[vertexS] = label[vertexW];
00115 size[vertexV] += size[vertexW];
00116 if(size[vertexV] < (2*size[vertexW])){
00117 uint32_t vertexT = vertexS;
00118 vertexS = child[vertexV];
00119 child[vertexV] = vertexT;
00120 }
00121 while(vertexS != 0){
00122 ancestor[vertexS] = vertexV;
00123 vertexS = child[vertexS];
00124 }
00125 }
00126
00127 LengauerTarjan::LengauerTarjan(uint32_t blockCount, BasicBlock* root, BasicBlock** blocks)
00128 {
00129
00130 reachableCount = 0;
00131 nodeCount = blockCount;
00132 locToBasicBlock = new BasicBlock*[blockCount+1];
00133 basicBlockToLoc = new uint32_t[blockCount+1];
00134
00135 locToBasicBlock[0] = NULL;
00136 basicBlockToLoc[blockCount] = 0;
00137
00138 uint32_t lastUnreachIdx = blockCount;
00139
00140 for(uint32_t i=0;i<blockCount;i++){
00141 if(blocks[i]->isNoPath()){
00142 locToBasicBlock[lastUnreachIdx] = blocks[i];
00143 basicBlockToLoc[blocks[i]->getIndex()] = lastUnreachIdx;
00144 lastUnreachIdx--;
00145 } else {
00146 reachableCount++;
00147 locToBasicBlock[reachableCount] = blocks[i];
00148 basicBlockToLoc[blocks[i]->getIndex()] = reachableCount;
00149 }
00150 }
00151
00152 ASSERT((lastUnreachIdx == reachableCount) &&
00153 "Fatal: when reachability is divided they should end up same index");
00154
00155 dom = new uint32_t[reachableCount+1];
00156
00157 parent = new uint32_t[reachableCount+1];
00158 ancestor = new uint32_t[reachableCount+1];
00159 child = new uint32_t[reachableCount+1];
00160 vertex = new uint32_t[reachableCount+1];
00161 label = new uint32_t[reachableCount+1];
00162 semi = new uint32_t[reachableCount+1];
00163 size = new uint32_t[reachableCount+1];
00164
00165 bucket = new LinkedList<uint32_t>[reachableCount+1];
00166
00167 for(uint32_t i=0;i<=reachableCount;i++){
00168 semi[i] = 0;
00169 }
00170 rootLoc = basicBlockToLoc[root->getIndex()];
00171 }
00172
00173 LengauerTarjan::~LengauerTarjan(){
00174 delete[] locToBasicBlock;
00175 delete[] basicBlockToLoc;
00176 delete[] parent;
00177 delete[] ancestor;
00178 delete[] child;
00179 delete[] vertex;
00180 delete[] label;
00181 delete[] semi;
00182 delete[] size;
00183 delete[] dom;
00184 delete[] bucket;
00185 }
00186
00187 void LengauerTarjan::immediateDominators(){
00188
00189 uint32_t dfsNo = 0;
00190 depthFirstSearch(rootLoc,&dfsNo);
00191
00192 size[0] = 0;
00193 label[0] = 0;
00194 semi[0] = 0;
00195
00196 for(int32_t i=reachableCount;i>1;i--){
00197 uint32_t vertexW = vertex[i];
00198
00199 BasicBlock* bb = locToBasicBlock[vertexW];
00200 uint32_t numOfSources = bb->getNumOfSources();
00201
00202 for(uint32_t j=0;j<numOfSources;j++){
00203 BasicBlock* source = bb->getSourceBlock(j);
00204 if(!source->isNoPath()){
00205 uint32_t vertexV = basicBlockToLoc[source->getIndex()];
00206 uint32_t vertexU = EVAL(vertexV);
00207 if(semi[vertexU] < semi[vertexW]){
00208 semi[vertexW] = semi[vertexU];
00209 }
00210 }
00211 }
00212
00213 bucket[vertex[semi[vertexW]]].insert(vertexW);
00214
00215 LINK(parent[vertexW],vertexW);
00216
00217 LinkedList<uint32_t>* bs = &(bucket[parent[vertexW]]);
00218 while(!bs->empty()){
00219 uint32_t vertexV = bs->shift();
00220 uint32_t vertexU = EVAL(vertexV);
00221 dom[vertexV] = ( semi[vertexU] < semi[vertexV] ) ? vertexU : parent[vertexW];
00222 }
00223 }
00224 for(uint32_t i=2;i<=reachableCount;i++){
00225 uint32_t vertexW = vertex[i];
00226 if(dom[vertexW] != vertex[semi[vertexW]]){
00227 dom[vertexW] = dom[dom[vertexW]];
00228 }
00229 }
00230
00231 dom[rootLoc] = 0;
00232 PRINT_DEBUG("ROOT is %d",rootLoc);
00233
00234 for(uint32_t i=1;i<=reachableCount;i++){
00235 uint32_t vertexW = vertex[i];
00236 BasicBlock* bb = locToBasicBlock[vertexW];
00237 ASSERT(!bb->isNoPath());
00238 BasicBlock* immDom = locToBasicBlock[dom[vertexW]];
00239 if(immDom){
00240 PRINT_DEBUG("Reachable : Immediate Dominator of %d is %d",bb->getIndex(),immDom->getIndex());
00241 bb->setImmDominator(immDom);
00242 } else {
00243 PRINT_DEBUG("Reachable : Immediate Dominator of %d is Entry",bb->getIndex());
00244 }
00245 }
00246 for(int32_t i=nodeCount;i>reachableCount;i--){
00247 BasicBlock* bb = locToBasicBlock[i];
00248 ASSERT(bb->isNoPath());
00249 BasicBlock* immDom = locToBasicBlock[rootLoc];
00250 PRINT_DEBUG("Un-Reachable : Immediate Dominator of %d is %d",bb->getIndex(),immDom->getIndex());
00251 bb->setImmDominator(immDom);
00252 }
00253 }