|
20 | 20 | #include <queue>
|
21 | 21 | #include <set>
|
22 | 22 | #include <stack>
|
| 23 | +#include <unordered_set> |
23 | 24 |
|
24 | 25 | using namespace llvm;
|
25 | 26 | #define DEBUG_TYPE "sample-profile-inference"
|
@@ -1218,10 +1219,23 @@ void extractWeights(const ProfiParams &Params, MinCostMaxFlow &Network,
|
1218 | 1219 | #ifndef NDEBUG
|
1219 | 1220 | /// Verify that the provided block/jump weights are as expected.
|
1220 | 1221 | void verifyInput(const FlowFunction &Func) {
|
1221 |
| - // Verify the entry block |
| 1222 | + // Verify entry and exit blocks |
1222 | 1223 | assert(Func.Entry == 0 && Func.Blocks[0].isEntry());
|
| 1224 | + size_t NumExitBlocks = 0; |
1223 | 1225 | for (size_t I = 1; I < Func.Blocks.size(); I++) {
|
1224 | 1226 | assert(!Func.Blocks[I].isEntry() && "multiple entry blocks");
|
| 1227 | + if (Func.Blocks[I].isExit()) |
| 1228 | + NumExitBlocks++; |
| 1229 | + } |
| 1230 | + assert(NumExitBlocks > 0 && "cannot find exit blocks"); |
| 1231 | + |
| 1232 | + // Verify that there are no parallel edges |
| 1233 | + for (auto &Block : Func.Blocks) { |
| 1234 | + std::unordered_set<uint64_t> UniqueSuccs; |
| 1235 | + for (auto &Jump : Block.SuccJumps) { |
| 1236 | + auto It = UniqueSuccs.insert(Jump->Target); |
| 1237 | + assert(It.second && "input CFG contains parallel edges"); |
| 1238 | + } |
1225 | 1239 | }
|
1226 | 1240 | // Verify CFG jumps
|
1227 | 1241 | for (auto &Block : Func.Blocks) {
|
@@ -1304,8 +1318,26 @@ void verifyOutput(const FlowFunction &Func) {
|
1304 | 1318 |
|
1305 | 1319 | } // end of anonymous namespace
|
1306 | 1320 |
|
1307 |
| -/// Apply the profile inference algorithm for a given function |
| 1321 | +/// Apply the profile inference algorithm for a given function and provided |
| 1322 | +/// profi options |
1308 | 1323 | void llvm::applyFlowInference(const ProfiParams &Params, FlowFunction &Func) {
|
| 1324 | + // Check if the function has samples and assign initial flow values |
| 1325 | + bool HasSamples = false; |
| 1326 | + for (FlowBlock &Block : Func.Blocks) { |
| 1327 | + if (Block.Weight > 0) |
| 1328 | + HasSamples = true; |
| 1329 | + Block.Flow = Block.Weight; |
| 1330 | + } |
| 1331 | + for (FlowJump &Jump : Func.Jumps) { |
| 1332 | + if (Jump.Weight > 0) |
| 1333 | + HasSamples = true; |
| 1334 | + Jump.Flow = Jump.Weight; |
| 1335 | + } |
| 1336 | + |
| 1337 | + // Quit early for functions with a single block or ones w/o samples |
| 1338 | + if (Func.Blocks.size() <= 1 || !HasSamples) |
| 1339 | + return; |
| 1340 | + |
1309 | 1341 | #ifndef NDEBUG
|
1310 | 1342 | // Verify the input data
|
1311 | 1343 | verifyInput(Func);
|
|
0 commit comments