Link cfg and dominator analysis in the context (#2946)

Fixes #2889
This commit is contained in:
Steven Perron 2019-10-08 10:16:18 -04:00 committed by GitHub
parent 5910bb8e94
commit 32f76efa6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 1 deletions

View File

@ -94,6 +94,14 @@ void IRContext::InvalidateAnalyses(IRContext::Analysis analyses_to_invalidate) {
if (analyses_to_invalidate & kAnalysisTypes) {
analyses_to_invalidate |= kAnalysisConstants;
}
// The dominator analysis hold the psuedo entry and exit nodes from the CFG.
// Also if the CFG change the dominators many changed as well, so the
// dominator analysis should be invalidated as well.
if (analyses_to_invalidate & kAnalysisCFG) {
analyses_to_invalidate |= kAnalysisDominatorAnalysis;
}
if (analyses_to_invalidate & kAnalysisDefUse) {
def_use_mgr_.reset(nullptr);
}

View File

@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/opt/ir_context.h"
#include <algorithm>
#include <memory>
#include <string>
@ -19,7 +21,6 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "source/opt/ir_context.h"
#include "source/opt/pass.h"
#include "test/opt/pass_fixture.h"
#include "test/opt/pass_utils.h"
@ -664,6 +665,90 @@ OpFunctionEnd)";
EXPECT_EQ(next_id_bound, 0);
EXPECT_EQ(current_bound, context->module()->id_bound());
}
TEST_F(IRContextTest, CfgAndDomAnalysis) {
const std::string text = R"(
OpCapability Shader
OpCapability Linkage
OpMemoryModel Logical GLSL450
%1 = OpTypeVoid
%2 = OpTypeFunction %1
%3 = OpFunction %1 None %2
%4 = OpLabel
OpReturn
OpFunctionEnd)";
std::unique_ptr<IRContext> ctx =
BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
// Building the dominator analysis should build the CFG.
ASSERT_TRUE(ctx->module()->begin() != ctx->module()->end());
ctx->GetDominatorAnalysis(&*ctx->module()->begin());
EXPECT_TRUE(ctx->AreAnalysesValid(IRContext::kAnalysisCFG));
EXPECT_TRUE(ctx->AreAnalysesValid(IRContext::kAnalysisDominatorAnalysis));
// Invalidating the CFG analysis should invalidate the dominator analysis.
ctx->InvalidateAnalyses(IRContext::kAnalysisCFG);
EXPECT_FALSE(ctx->AreAnalysesValid(IRContext::kAnalysisCFG));
EXPECT_FALSE(ctx->AreAnalysesValid(IRContext::kAnalysisDominatorAnalysis));
}
TEST_F(IRContextTest, AsanErrorTest) {
std::string shader = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %4 "main"
OpExecutionMode %4 OriginUpperLeft
OpSource ESSL 310
OpName %4 "main"
OpName %8 "x"
OpName %10 "y"
OpDecorate %8 RelaxedPrecision
OpDecorate %10 RelaxedPrecision
OpDecorate %11 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%7 = OpTypePointer Function %6
%9 = OpConstant %6 1
%4 = OpFunction %2 None %3
%5 = OpLabel
%8 = OpVariable %7 Function
%10 = OpVariable %7 Function
OpStore %8 %9
%11 = OpLoad %6 %8
OpBranch %20
%20 = OpLabel
%21 = OpPhi %6 %11 %5
OpStore %10 %21
OpReturn
OpFunctionEnd
)";
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto consumer = nullptr;
const auto context = BuildModule(
env, consumer, shader, SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
opt::Function* fun =
context->cfg()->block(5)->GetParent(); // Computes the CFG analysis
opt::DominatorAnalysis* dom = nullptr;
dom = context->GetDominatorAnalysis(fun); // Computes the dominator analysis,
// which depends on the CFG
// analysis
context->InvalidateAnalysesExceptFor(
opt::IRContext::Analysis::kAnalysisDominatorAnalysis); // Invalidates the
// CFG analysis
dom = context->GetDominatorAnalysis(
fun); // Recompute the CFG analysis because the Dominator tree uses it.
auto bb = dom->ImmediateDominator(5);
std::cout
<< bb->id(); // Make sure asan does not complain about use after free.
}
} // namespace
} // namespace opt
} // namespace spvtools