LLVM: lib/Transforms/IPO/BlockExtractor.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

26

27using namespace llvm;

28

29#define DEBUG_TYPE "block-extractor"

30

31STATISTIC(NumExtracted, "Number of basic blocks extracted");

32

35 cl::desc("A file containing list of basic blocks to extract"), cl::Hidden);

36

39 cl::desc("Erase the existing functions"),

41namespace {

42class BlockExtractor {

43public:

44 BlockExtractor(bool EraseFunctions) : EraseFunctions(EraseFunctions) {}

45 bool runOnModule(Module &M);

46 void

47 init(const std::vector<std::vector<BasicBlock *>> &GroupsOfBlocksToExtract) {

48 GroupsOfBlocks = GroupsOfBlocksToExtract;

51 }

52

53private:

54 std::vector<std::vector<BasicBlock *>> GroupsOfBlocks;

55 bool EraseFunctions;

56

58 BlocksByName;

59

61 void splitLandingPadPreds(Function &F);

62};

63

64}

65

66

67void BlockExtractor::loadFile() {

69 if (ErrOrBuf.getError())

71

72 auto &Buf = *ErrOrBuf;

73 SmallVector<StringRef, 16> Lines;

74 Buf->getBuffer().split(Lines, '\n', -1,

75 false);

76 for (const auto &Line : Lines) {

78 Line.split(LineSplit, ' ', -1,

79 false);

80 if (LineSplit.empty())

81 continue;

82 if (LineSplit.size()!=2)

84 "Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'");

86 LineSplit[1].split(BBNames, ';', -1,

87 false);

88 if (BBNames.empty())

90 BlocksByName.push_back(

91 {std::string(LineSplit[0]), {BBNames.begin(), BBNames.end()}});

92 }

93}

94

95

96

97void BlockExtractor::splitLandingPadPreds(Function &F) {

98 for (BasicBlock &BB : F) {

99 for (Instruction &I : BB) {

101 continue;

105

106

107

108 bool Split = false;

110 if (PredBB->isLandingPad() && PredBB != Parent &&

113 break;

114 }

115 }

116

117 if (!Split)

118 continue;

119

122 }

123 }

124}

125

126bool BlockExtractor::runOnModule(Module &M) {

128

129

131 for (Function &F : M) {

132 splitLandingPadPreds(F);

134 }

135

136

137 unsigned NextGroupIdx = GroupsOfBlocks.size();

138 GroupsOfBlocks.resize(NextGroupIdx + BlocksByName.size());

139 for (const auto &BInfo : BlocksByName) {

140 Function *F = M.getFunction(BInfo.first);

141 if (F)

143 "Invalid function name specified in the input file");

144 for (const auto &BBInfo : BInfo.second) {

146 *F, [&](const BasicBlock &BB) { return BB.getName() == BBInfo; });

147 if (Res == F->end())

149 GroupsOfBlocks[NextGroupIdx].push_back(&*Res);

150 }

151 ++NextGroupIdx;

152 }

153

154

155 for (auto &BBs : GroupsOfBlocks) {

157 for (BasicBlock *BB : BBs) {

158

163 << "\n");

164 BlocksToExtractVec.push_back(BB);

166 BlocksToExtractVec.push_back(II->getUnwindDest());

167 ++NumExtracted;

169 }

170 CodeExtractorAnalysisCache CEAC(*BBs[0]->getParent());

171 Function *F = CodeExtractor(BlocksToExtractVec).extractCodeRegion(CEAC);

172 if (F)

173 LLVM_DEBUG(dbgs() << "Extracted group '" << (*BBs.begin())->getName()

174 << "' in: " << F->getName() << '\n');

175 else

177 << (*BBs.begin())->getName() << "'\n");

178 }

179

180

182 for (Function *F : Functions) {

183 LLVM_DEBUG(dbgs() << "BlockExtractor: Trying to delete " << F->getName()

184 << "\n");

185 F->deleteBody();

186 }

187

188 for (Function &F : M)

191 }

192

194}

195

197 std::vector<std::vector<BasicBlock *>> &&GroupsOfBlocks,

198 bool EraseFunctions)

199 : GroupsOfBlocks(GroupsOfBlocks), EraseFunctions(EraseFunctions) {}

200

203 BlockExtractor BE(EraseFunctions);

204 BE.init(GroupsOfBlocks);

207}

static const Function * getParent(const Value *V)

static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

Machine Check Debug Module

uint64_t IntrinsicInst * II

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

const Function * getParent() const

Return the enclosing method, or null if none.

const Instruction * getTerminator() const LLVM_READONLY

Returns the terminator instruction if the block is well formed or null if the block is not well forme...

Module * getParent()

Get the module that this global value is contained inside of...

@ ExternalLinkage

Externally visible function.

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

A Module instance is used to store all the information related to an LLVM module.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

void push_back(const T &Elt)

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

@ BasicBlock

Various leaf nodes.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI void SplitLandingPadPredecessors(BasicBlock *OrigBB, ArrayRef< BasicBlock * > Preds, const char *Suffix, const char *Suffix2, SmallVectorImpl< BasicBlock * > &NewBBs, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)

This method transforms the landing pad, OrigBB, by introducing two new basic blocks into the function...

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

auto predecessors(const MachineBasicBlock *BB)

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

LLVM_ABI void reportFatalUsageError(Error Err)

Report a fatal error that does not indicate a bug in LLVM.