#include #include inline int min(int a,int b) { if (aID,AdjList[i]->ST,AdjList[i]->Low,AdjList[i]->SccNum); // } Init(); } } extern int VisitID,VATrailer,ETDummyA,FinishID,QDone,QProc; int SccCount; extern CVertex Vertex0; extern CVertex Vertex1; extern CVertex Vertex2; extern CVertex Vertex3; extern CVertex Vertex4; extern CVertex Vertex5; extern CVertex Vertex6; extern CVertex Vertex7; extern CVertex Vertex8; extern CVertex Vertex9; extern CVertex Vertex10; extern CVertex Vertex11; extern CVertex Vertex12; extern CVertex Vertex13; extern CVertex Vertex14; extern CVertex Vertex15; extern CVertex Vertex16; extern CVertex Vertex17; extern CVertex Vertex18; extern CVertex Vertex19; extern CVertex Vertex20; extern CVertex Vertex21; extern CVertex Vertex1D; extern CVertex Vertex2D; extern CVertex Vertex3D; extern CVertex Vertex4D; extern CVertex Vertex5D; extern CVertex Vertex6D; extern CVertex Vertex7D; extern CVertex Vertex8D; extern CVertex Vertex9D; extern CVertex Vertex10D; extern CVertex Vertex11D; extern CVertex Vertex12D; extern CVertex Vertex13D; extern CVertex Vertex14D; extern CVertex Vertex15D; extern CVertex Vertex16D; extern CVertex Vertex17D; extern CVertex Vertex18D; extern CVertex Vertex19D; extern CVertex Vertex20D; extern CVertex Vertex21D; extern CVertex ETDummy; extern CVertex Trailer; extern CVertex QHead; extern CVertex QTail; CVertex * AdjList[21] = {&Vertex1,&Vertex2,&Vertex3,&Vertex4, &Vertex5,&Vertex6,&Vertex7,&Vertex8, &Vertex9,&Vertex10,&Vertex11,&Vertex12, &Vertex13,&Vertex14,&Vertex15,&Vertex16, &Vertex17,&Vertex18,&Vertex19,&Vertex20, &Vertex21}; CEdge V1F = {NULL,&Vertex1,&Vertex1D}; CEdge V1E2 = {&V1F,&Vertex1,&Vertex4}; CEdge V1E1 = {&V1E2,&Vertex1,&Vertex2}; CEdge V2F = {NULL,&Vertex2,&Vertex2D}; CEdge V2E2 = {&V2F,&Vertex2,&Vertex6}; CEdge V2E1 = {&V2E2,&Vertex2,&Vertex3}; CEdge V3F = {NULL,&Vertex3,&Vertex3D}; CEdge V3E1 = {&V3F,&Vertex3,&Vertex11}; CEdge V4F = {NULL,&Vertex4,&Vertex4D}; CEdge V4E2 = {&V4F,&Vertex4,&Vertex7}; CEdge V4E1 = {&V4E2,&Vertex4,&Vertex8}; CEdge V5F = {NULL,&Vertex5,&Vertex5D}; CEdge V5E2 = {&V5F,&Vertex5,&Vertex1}; CEdge V5E1 = {&V5E2,&Vertex5,&Vertex9}; CEdge V6F = {NULL,&Vertex6,&Vertex6D}; CEdge V6E1 = {&V6F,&Vertex6,&Vertex9}; CEdge V7F = {NULL,&Vertex7,&Vertex7D}; CEdge V8F = {NULL,&Vertex8,&Vertex8D}; CEdge V8E2 = {&V8F,&Vertex8,&Vertex12}; CEdge V8E1 = {&V8E2,&Vertex8,&Vertex13}; CEdge V9F = {NULL,&Vertex9,&Vertex9D}; CEdge V9E1 = {&V9F,&Vertex9,&Vertex14}; CEdge V10F = {NULL,&Vertex10,&Vertex10D}; CEdge V10E1 = {&V10F,&Vertex10,&Vertex18}; CEdge V11F = {NULL,&Vertex11,&Vertex11D}; CEdge V11E2 = {&V11F,&Vertex11,&Vertex10}; CEdge V11E1 = {&V11E2,&Vertex11,&Vertex15}; CEdge V12F = {NULL,&Vertex12,&Vertex12D}; CEdge V12E2 = {&V12F,&Vertex12,&Vertex7}; CEdge V12E1 = {&V12E2,&Vertex12,&Vertex16}; CEdge V13F = {NULL,&Vertex13,&Vertex13D}; CEdge V13E1 = {&V13F,&Vertex13,&Vertex5}; CEdge V14F = {NULL,&Vertex14,&Vertex14D}; CEdge V14E1 = {&V14F,&Vertex14,&Vertex17}; CEdge V15F = {NULL,&Vertex15,&Vertex15D}; CEdge V15E1 = {&V15F,&Vertex15,&Vertex3}; CEdge V16F = {NULL,&Vertex16,&Vertex16D}; CEdge V16E1 = {&V16F,&Vertex16,&Vertex13}; CEdge V17F = {NULL,&Vertex17,&Vertex17D}; CEdge V17E1 = {&V17F,&Vertex17,&Vertex13}; CEdge V18F = {NULL,&Vertex18,&Vertex18D}; CEdge V18E2 = {&V18F,&Vertex18,&Vertex11}; CEdge V18E1 = {&V18E2,&Vertex18,&Vertex21}; CEdge V19F = {NULL,&Vertex19,&Vertex19D}; CEdge V19E2 = {&V19F,&Vertex19,&Vertex21}; CEdge V19E1 = {&V19E2,&Vertex19,&Vertex7}; CEdge V20F = {NULL,&Vertex20,&Vertex20D}; CEdge V20E1 = {&V20F,&Vertex20,&Vertex19}; CEdge V21F = {NULL,&Vertex21,&Vertex21D}; CEdge V21E1 = {&V21F,&Vertex21,&Vertex20}; CEdge EdgeTrailer = {NULL,NULL,&ETDummy}; CVertex Vertex0 = {NULL,&Vertex1,NULL,NULL,NULL,NULL,0,0,0,NULL,NULL,NULL}; CVertex Vertex1 = {&Vertex0,&Vertex2,&VisitID,&V1E1,&V1F,NULL,0,0,0,1,NULL,NULL,&QProc}; CVertex Vertex2 = {&Vertex1,&Vertex3,&VisitID,&V2E1,&V2F,NULL,0,0,0,2,NULL,NULL,&QProc}; CVertex Vertex3 = {&Vertex2,&Vertex4,&VisitID,&V3E1,&V3F,NULL,0,0,0,3,NULL,NULL,&QProc}; CVertex Vertex4 = {&Vertex3,&Vertex5,&VisitID,&V4E1,&V4F,NULL,0,0,0,4,NULL,NULL,&QProc}; CVertex Vertex5 = {&Vertex4,&Vertex6,&VisitID,&V5E1,&V5F,NULL,0,0,0,5,NULL,NULL,&QProc}; CVertex Vertex6 = {&Vertex5,&Vertex7,&VisitID,&V6E1,&V6F,NULL,0,0,0,6,NULL,NULL,&QProc}; CVertex Vertex7 = {&Vertex6,&Vertex8,&VisitID,&V7F,&V7F,NULL,0,0,0,7,NULL,NULL,&QProc}; CVertex Vertex8 = {&Vertex7,&Vertex9,&VisitID,&V8E1,&V8F,NULL,0,0,0,8,NULL,NULL,&QProc}; CVertex Vertex9 = {&Vertex8,&Vertex10,&VisitID,&V9E1,&V9F,NULL,0,0,0,9,NULL,NULL,&QProc}; CVertex Vertex10 = {&Vertex9,&Vertex11,&VisitID,&V10E1,&V10F,NULL,0,0,0,10,NULL,NULL,&QProc}; CVertex Vertex11 = {&Vertex10,&Vertex12,&VisitID,&V11E1,&V11F,NULL,0,0,0,11,NULL,NULL,&QProc}; CVertex Vertex12 = {&Vertex11,&Vertex13,&VisitID,&V12E1,&V12F,NULL,0,0,0,12,NULL,NULL,&QProc}; CVertex Vertex13 = {&Vertex12,&Vertex14,&VisitID,&V13E1,&V13F,NULL,0,0,0,13,NULL,NULL,&QProc}; CVertex Vertex14 = {&Vertex13,&Vertex15,&VisitID,&V14E1,&V14F,NULL,0,0,0,14,NULL,NULL,&QProc}; CVertex Vertex15 = {&Vertex14,&Vertex16,&VisitID,&V15E1,&V15F,NULL,0,0,0,15,NULL,NULL,&QProc}; CVertex Vertex16 = {&Vertex15,&Vertex17,&VisitID,&V16E1,&V16F,NULL,0,0,0,16,NULL,NULL,&QProc}; CVertex Vertex17 = {&Vertex16,&Vertex18,&VisitID,&V17E1,&V17F,NULL,0,0,0,17,NULL,NULL,&QProc}; CVertex Vertex18 = {&Vertex17,&Vertex19,&VisitID,&V18E1,&V18F,NULL,0,0,0,18,NULL,NULL,&QProc}; CVertex Vertex19 = {&Vertex18,&Vertex20,&VisitID,&V19E1,&V19F,NULL,0,0,0,19,NULL,NULL,&QProc}; CVertex Vertex20 = {&Vertex19,&Vertex21,&VisitID,&V20E1,&V20F,NULL,0,0,0,20,NULL,NULL,&QProc}; CVertex Vertex21 = {&Vertex20,&Trailer,&VisitID,&V21E1,&V21F,NULL,0,0,0,21,NULL,NULL,&QProc}; CVertex Trailer = {&Vertex21,NULL,&VATrailer,NULL,NULL,NULL,0,0,0,0,NULL,NULL,NULL}; CVertex ETDummy = {NULL,NULL,&ETDummyA,NULL,NULL,NULL,0,0,0,0,NULL,NULL,NULL}; CVertex Vertex1D = {&Vertex1,NULL,&FinishID,NULL,NULL,NULL,0,0,0,1,NULL,NULL,NULL}; CVertex Vertex2D = {&Vertex2,NULL,&FinishID,NULL,NULL,NULL,0,0,0,2,NULL,NULL,NULL}; CVertex Vertex3D = {&Vertex3,NULL,&FinishID,NULL,NULL,NULL,0,0,0,3,NULL,NULL,NULL}; CVertex Vertex4D = {&Vertex4,NULL,&FinishID,NULL,NULL,NULL,0,0,0,4,NULL,NULL,NULL}; CVertex Vertex5D = {&Vertex5,NULL,&FinishID,NULL,NULL,NULL,0,0,0,5,NULL,NULL,NULL}; CVertex Vertex6D = {&Vertex6,NULL,&FinishID,NULL,NULL,NULL,0,0,0,6,NULL,NULL,NULL}; CVertex Vertex7D = {&Vertex7,NULL,&FinishID,NULL,NULL,NULL,0,0,0,7,NULL,NULL,NULL}; CVertex Vertex8D = {&Vertex8,NULL,&FinishID,NULL,NULL,NULL,0,0,0,8,NULL,NULL,NULL}; CVertex Vertex9D = {&Vertex9,NULL,&FinishID,NULL,NULL,NULL,0,0,0,9,NULL,NULL,NULL}; CVertex Vertex10D = {&Vertex10,NULL,&FinishID,NULL,NULL,NULL,0,0,0,10,NULL,NULL,NULL}; CVertex Vertex11D = {&Vertex11,NULL,&FinishID,NULL,NULL,NULL,0,0,0,11,NULL,NULL,NULL}; CVertex Vertex12D = {&Vertex12,NULL,&FinishID,NULL,NULL,NULL,0,0,0,12,NULL,NULL,NULL}; CVertex Vertex13D = {&Vertex13,NULL,&FinishID,NULL,NULL,NULL,0,0,0,13,NULL,NULL,NULL}; CVertex Vertex14D = {&Vertex14,NULL,&FinishID,NULL,NULL,NULL,0,0,0,14,NULL,NULL,NULL}; CVertex Vertex15D = {&Vertex15,NULL,&FinishID,NULL,NULL,NULL,0,0,0,15,NULL,NULL,NULL}; CVertex Vertex16D = {&Vertex16,NULL,&FinishID,NULL,NULL,NULL,0,0,0,16,NULL,NULL,NULL}; CVertex Vertex17D = {&Vertex17,NULL,&FinishID,NULL,NULL,NULL,0,0,0,17,NULL,NULL,NULL}; CVertex Vertex18D = {&Vertex18,NULL,&FinishID,NULL,NULL,NULL,0,0,0,18,NULL,NULL,NULL}; CVertex Vertex19D = {&Vertex19,NULL,&FinishID,NULL,NULL,NULL,0,0,0,19,NULL,NULL,NULL}; CVertex Vertex20D = {&Vertex20,NULL,&FinishID,NULL,NULL,NULL,0,0,0,20,NULL,NULL,NULL}; CVertex Vertex21D = {&Vertex21,NULL,&FinishID,NULL,NULL,NULL,0,0,0,21,NULL,NULL,NULL}; CVertex DummyHead = {NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,NULL,NULL,NULL}; CEdge DummyEdge = {NULL,&DummyHead,&DummyHead}; CVertex QHead = {NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,NULL,&QTail,NULL}; CVertex QTail = {NULL,NULL,NULL,NULL,NULL,NULL,0,0,0,0,&QHead,NULL,&QDone}; CVertex * Current; CVertex * QStart; void FindCC() { register long Tis; register CVertex * QTis; register CEdge * EQ; register CEdge * Ted; Time = 0; SccCount = 0; Current = &Vertex0; NextVertex: asm("ETDummyA:\n\t.global\tETDummyA\n"); // coming here is equivalent to a high-level call Current = Current->Next; EQ = &EdgeTrailer; Tis = (long)Current; Ted = &DummyEdge; goto * ((CVertex *)Tis)->Visit; Visit1: asm("VisitID:\n\t.global\tVisitID\n"); // Queue Me ((CVertex *)Tis)->QNext = &QTail; ((CVertex *)Tis)->QPrev = QTail.QPrev; QTail.QPrev = (CVertex *)Tis; ((CVertex *)Tis)->QPrev->QNext = (CVertex *)Tis; // change the visit routine ((CVertex *)Tis)->Visit = &&Visit2; // Hook me into tree. Needed for termination ((CVertex *)Tis)->Parent = Ted->Parent; // Compute StartTime Time++; ((CVertex *)Tis)->ST = Time; ((CVertex *)Tis)->Low = Time; // Queue all edges for processing ((CVertex *)Tis)->EdgeTail->Next = EQ; EQ = ((CVertex *)Tis)->EdgeHead; // Go to next edge Tis = (long)(EQ->Vertex); Ted = EQ; EQ = EQ->Next; goto * ((CVertex *)Tis)->Visit; Visit2: // Check for forward edge if (((CVertex *)Tis)->ST < Ted->Parent->ST) { if (((CVertex *)Tis)->ST < Ted->Parent->Low) { Ted->Parent->Low = ((CVertex *)Tis)->ST; } } // Go to next edge Tis = (long)(EQ->Vertex); Ted = EQ; EQ = EQ->Next; goto * ((CVertex *)Tis)->Visit; Visit3: // marked vertex // Go to next edge Tis = (long)(EQ->Vertex); Ted = EQ; EQ = EQ->Next; goto * ((CVertex *)Tis)->Visit; QProc: asm("QProc:\n\t.global\tQProc\n"); QTis->Visit = &&Visit3; QTis->SccNum = SccCount; QTis = QTis->QNext; goto *QTis->Qpr; QDone: asm("QDone:\n\t.global\tQDone\n"); // unhook the most recent queue QStart->QNext = &QTail; QTail.QPrev = QStart; // Go to next edge Tis = (long)(EQ->Vertex); Ted = EQ; EQ = EQ->Next; goto * ((CVertex *)Tis)->Visit; Finish: asm("FinishID:\n\t.global\tFinishID\n"); // Get the real block Tis = (long)(((CVertex *)Tis)->Prev); // Push up tree if (((CVertex *)Tis)->Low < ((CVertex *)Tis)->Parent->Low) { ((CVertex *)Tis)->Parent->Low = ((CVertex *)Tis)->Low; } // detect SCC if (((CVertex *)Tis)->Low == ((CVertex *)Tis)->ST) { SccCount++; QTis = (CVertex *)Tis; QStart = ((CVertex *)Tis)->QPrev; goto *QTis->Qpr; } // Go to next edge Tis = (long)(EQ->Vertex); Ted = EQ; EQ = EQ->Next; goto * ((CVertex *)Tis)->Visit; VTrailer: asm("VATrailer:\n\t.global\tVATrailer\n"); return; } void Init() { CVertex *Prev; CVertex *Next; long i; for (i=0 ; iVisit = &VisitID; AdjList[i]->Parent = NULL; AdjList[i]->ST = 0; AdjList[i]->Low = 0; AdjList[i]->SccNum = 0; } }