diff options
author | Guy David <guyda96@gmail.com> | 2025-09-16 13:08:12 -0700 |
---|---|---|
committer | Guy David <guyda96@gmail.com> | 2025-09-16 13:08:12 -0700 |
commit | 1589c07c93ec5c14123e6d5145d25df3a69a37bc (patch) | |
tree | ee8c950f78d06db91d6863aeac704d4ec6e39e25 | |
parent | b369237c98906891f9e56fd4be4109a25b79e3e9 (diff) | |
download | llvm-users/guy-david/separate-indirectbr.zip llvm-users/guy-david/separate-indirectbr.tar.gz llvm-users/guy-david/separate-indirectbr.tar.bz2 |
Separate indirectbrusers/guy-david/separate-indirectbr
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 21 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 11 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 5 |
4 files changed, 29 insertions, 26 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index d960d51..5d41a4c 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -545,6 +545,9 @@ class CFGBuilder { using LabelSetTy = llvm::SmallSetVector<LabelDecl *, 8>; LabelSetTy AddressTakenLabels; + // A list of indirect goto dispatch blocks (one per indirect goto statement). + std::vector<CFGBlock *> IndirectGotoBlocks; + // Information about the currently visited C++ object construction site. // This is set in the construction trigger and read when the constructor // or a function that returns an object by value is being visited. @@ -1751,8 +1754,8 @@ std::unique_ptr<CFG> CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { } } - // Add successors to the Indirect Goto Dispatch block (if we have one). - if (CFGBlock *B = cfg->getIndirectGotoBlock()) + // Add successors to the Indirect Goto Dispatch blocks (one per indirect goto statement). + for (CFGBlock *B : IndirectGotoBlocks) { for (LabelDecl *LD : AddressTakenLabels) { // Lookup the target block. LabelMapTy::iterator LI = LabelMap.find(LD); @@ -1763,6 +1766,7 @@ std::unique_ptr<CFG> CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) { addSuccessor(B, LI->second.block); } + } // Create an empty entry block that has no predecessors. cfg->setEntry(createBlock()); @@ -5028,13 +5032,8 @@ CFGBlock *CFGBuilder::VisitConstantExpr(ConstantExpr *E, AddStmtChoice asc) { } CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { - // Lazily create the indirect-goto dispatch block if there isn't one already. - CFGBlock *IBlock = cfg->getIndirectGotoBlock(); - - if (!IBlock) { - IBlock = createBlock(false); - cfg->setIndirectGotoBlock(IBlock); - } + // Create a new indirect-goto dispatch block for each statement. + CFGBlock *IBlock = createBlock(false); // IndirectGoto is a control-flow statement. Thus we stop processing the // current block and create a new one. @@ -5044,6 +5043,10 @@ CFGBlock *CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt *I) { Block = createBlock(false); Block->setTerminator(I); addSuccessor(Block, IBlock); + + // Store this dispatch block so we can connect it to labels later + IndirectGotoBlocks.push_back(IBlock); + return addStmt(I->getTarget()); } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 031ef73..9d19cdb 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -858,21 +858,17 @@ void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) { return; } - // Ensure that we have an i8* for our PHI node. + // Ensure that we have an i8* for the indirect branch. llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()), Int8PtrTy, "addr"); - llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); - - // Get the basic block for the indirect goto. - llvm::BasicBlock *IndGotoBB = GetIndirectGotoBlock(); - // The first instruction in the block has to be the PHI for the switch dest, - // add an entry for this branch. - cast<llvm::PHINode>(IndGotoBB->begin())->addIncoming(V, CurBB); + // Create a new indirect branch instruction for this statement + llvm::IndirectBrInst *IndBr = Builder.CreateIndirectBr(V); - EmitBranch(IndGotoBB); - if (CurBB && CurBB->getTerminator()) - addInstToCurrentSourceAtom(CurBB->getTerminator(), nullptr); + // Add all address-taken labels as possible destinations + for (llvm::BasicBlock *BB : AddressTakenLabels) { + IndBr->addDestination(BB); + } } void CodeGenFunction::EmitIfStmt(const IfStmt &S) { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b2fe917..73a604f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2287,14 +2287,13 @@ CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) { } llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) { - // Make sure that there is a block for the indirect goto. - if (!IndirectBranch) - GetIndirectGotoBlock(); - llvm::BasicBlock *BB = getJumpDestForLabel(L).getBlock(); - // Make sure the indirect branch includes all of the address-taken blocks. - IndirectBranch->addDestination(BB); + // Keep track of this address-taken label for indirect goto statements + if (llvm::find(AddressTakenLabels, BB) == AddressTakenLabels.end()) { + AddressTakenLabels.push_back(BB); + } + return llvm::BlockAddress::get(CurFn->getType(), BB); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index c02ac18..fea0a46 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1527,6 +1527,11 @@ private: /// codegen'd as a jump to the IndirectBranch's basic block. llvm::IndirectBrInst *IndirectBranch = nullptr; + /// AddressTakenLabels - Collection of address-taken labels for indirect gotos. + /// Each indirect goto statement will create its own indirectbr instruction + /// with all these labels as possible destinations. + llvm::SmallVector<llvm::BasicBlock *, 8> AddressTakenLabels; + /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C /// decls. DeclMapTy LocalDeclMap; |