Revert "[XRay] Add a BlockVerifier visitor for FDR Records"

This reverts commit r341628.

llvm-svn: 341631
This commit is contained in:
Dean Michael Berris 2018-09-07 03:38:26 +00:00
parent 30e129f256
commit f904839144
5 changed files with 0 additions and 393 deletions

View File

@ -1,69 +0,0 @@
//===- BlockVerifier.h - FDR Block Verifier -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// An implementation of the RecordVisitor which verifies a sequence of records
// associated with a block, following the FDR mode log format's specifications.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
#define LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_
#include "llvm/XRay/FDRRecords.h"
#include <array>
#include <bitset>
namespace llvm {
namespace xray {
class BlockVerifier : public RecordVisitor {
public:
// We force State elements to be size_t, to be used as indices for containers.
enum class State : std::size_t {
Unknown,
BufferExtents,
NewBuffer,
WallClockTime,
PIDEntry,
NewCPUId,
TSCWrap,
CustomEvent,
Function,
CallArg,
EndOfBuffer,
StateMax,
};
private:
// We keep track of the current record seen by the verifier.
State CurrentRecord = State::Unknown;
// Transitions the current record to the new record, records an error on
// invalid transitions.
Error transition(State To);
public:
Error visit(BufferExtents &) override;
Error visit(WallclockRecord &) override;
Error visit(NewCPUIDRecord &) override;
Error visit(TSCWrapRecord &) override;
Error visit(CustomEventRecord &) override;
Error visit(CallArgRecord &) override;
Error visit(PIDRecord &) override;
Error visit(NewBufferRecord &) override;
Error visit(EndBufferRecord &) override;
Error visit(FunctionRecord &) override;
Error verify();
void reset();
};
} // namespace xray
} // namespace llvm
#endif // LLVM_INCLUDE_LLVM_XRAY_BLOCKVERIFIER_H_

View File

@ -1,182 +0,0 @@
//===- BlockVerifier.cpp - FDR Block Verifier -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/XRay/BlockVerifier.h"
#include "llvm/Support/Error.h"
namespace llvm {
namespace xray {
namespace {
constexpr unsigned long long mask(BlockVerifier::State S) {
return 1uLL << static_cast<std::size_t>(S);
}
constexpr std::size_t number(BlockVerifier::State S) {
return static_cast<std::size_t>(S);
}
StringRef recordToString(BlockVerifier::State R) {
switch (R) {
case BlockVerifier::State::BufferExtents:
return "BufferExtents";
case BlockVerifier::State::NewBuffer:
return "NewBuffer";
case BlockVerifier::State::WallClockTime:
return "WallClockTime";
case BlockVerifier::State::PIDEntry:
return "PIDEntry";
case BlockVerifier::State::NewCPUId:
return "NewCPUId";
case BlockVerifier::State::TSCWrap:
return "TSCWrap";
case BlockVerifier::State::CustomEvent:
return "CustomEvent";
case BlockVerifier::State::Function:
return "Function";
case BlockVerifier::State::CallArg:
return "CallArg";
case BlockVerifier::State::EndOfBuffer:
return "EndOfBuffer";
case BlockVerifier::State::StateMax:
case BlockVerifier::State::Unknown:
return "Unknown";
}
}
} // namespace
Error BlockVerifier::transition(State To) {
using ToSet = std::bitset<number(State::StateMax)>;
static constexpr std::array<const std::tuple<State, ToSet>,
number(State::StateMax)>
TransitionTable{{{State::Unknown,
{mask(State::BufferExtents) | mask(State::NewBuffer)}},
{State::BufferExtents, {mask(State::NewBuffer)}},
{State::NewBuffer, {mask(State::WallClockTime)}},
{State::WallClockTime,
{mask(State::PIDEntry) | mask(State::NewCPUId)}},
{State::PIDEntry, {mask(State::NewCPUId)}},
{State::NewCPUId,
{mask(State::NewCPUId) | mask(State::TSCWrap) |
mask(State::CustomEvent) | mask(State::Function) |
mask(State::EndOfBuffer)}},
{State::TSCWrap,
{mask(State::TSCWrap) | mask(State::NewCPUId) |
mask(State::CustomEvent) | mask(State::Function) |
mask(State::EndOfBuffer)}},
{State::CustomEvent,
{mask(State::CustomEvent) | mask(State::TSCWrap) |
mask(State::NewCPUId) | mask(State::Function) |
mask(State::EndOfBuffer)}},
{State::Function,
{mask(State::Function) | mask(State::TSCWrap) |
mask(State::NewCPUId) | mask(State::CustomEvent) |
mask(State::CallArg) | mask(State::EndOfBuffer)}},
{State::CallArg,
{mask(State::CallArg) | mask(State::Function) |
mask(State::TSCWrap) | mask(State::NewCPUId) |
mask(State::CustomEvent) | mask(State::EndOfBuffer)}},
{State::EndOfBuffer, {}}}};
if (CurrentRecord >= State::StateMax)
return createStringError(
std::make_error_code(std::errc::executable_format_error),
"BUG (BlockVerifier): Cannot find transition table entry for %s, "
"transitioning to %s.",
recordToString(CurrentRecord).data(), recordToString(To).data());
// If we're at an EndOfBuffer record, we ignore anything that follows that
// isn't a NewBuffer record.
if (CurrentRecord == State::EndOfBuffer && To != State::NewBuffer)
return Error::success();
auto &Mapping = TransitionTable[number(CurrentRecord)];
auto &From = std::get<0>(Mapping);
auto &Destinations = std::get<1>(Mapping);
assert(From == CurrentRecord && "BUG: Wrong index for record mapping.");
if ((Destinations & ToSet(mask(To))) == 0)
return createStringError(
std::make_error_code(std::errc::executable_format_error),
"BlockVerifier: Invalid transition from %s to %s.",
recordToString(CurrentRecord).data(), recordToString(To).data());
CurrentRecord = To;
return Error::success();
} // namespace xray
Error BlockVerifier::visit(BufferExtents &) {
return transition(State::BufferExtents);
}
Error BlockVerifier::visit(WallclockRecord &) {
return transition(State::WallClockTime);
}
Error BlockVerifier::visit(NewCPUIDRecord &) {
return transition(State::NewCPUId);
}
Error BlockVerifier::visit(TSCWrapRecord &) {
return transition(State::TSCWrap);
}
Error BlockVerifier::visit(CustomEventRecord &) {
return transition(State::CustomEvent);
}
Error BlockVerifier::visit(CallArgRecord &) {
return transition(State::CallArg);
}
Error BlockVerifier::visit(PIDRecord &) { return transition(State::PIDEntry); }
Error BlockVerifier::visit(NewBufferRecord &) {
return transition(State::NewBuffer);
}
Error BlockVerifier::visit(EndBufferRecord &) {
return transition(State::EndOfBuffer);
}
Error BlockVerifier::visit(FunctionRecord &) {
return transition(State::Function);
}
Error BlockVerifier::verify() {
// The known terminal conditions are the following:
switch (CurrentRecord) {
case State::EndOfBuffer:
case State::NewCPUId:
case State::CustomEvent:
case State::Function:
case State::CallArg:
case State::TSCWrap:
return Error::success();
default:
return createStringError(
std::make_error_code(std::errc::executable_format_error),
"BlockVerifier: Invalid terminal condition %s, malformed block.",
recordToString(CurrentRecord).data());
}
}
void BlockVerifier::reset() { CurrentRecord = State::Unknown; }
} // namespace xray
} // namespace llvm

View File

@ -1,6 +1,5 @@
add_llvm_library(LLVMXRay
BlockIndexer.cpp
BlockVerifier.cpp
FDRRecordProducer.cpp
FDRRecords.cpp
FDRTraceWriter.cpp

View File

@ -1,13 +1,11 @@
set(LLVM_LINK_COMPONENTS
Support
XRay
TestingSupport
)
add_llvm_unittest(XRayTests
ProfileTest.cpp
FDRBlockIndexerTest.cpp
FDRBlockVerifierTest.cpp
FDRProducerConsumerTest.cpp
FDRRecordPrinterTest.cpp
FDRTraceWriterTest.cpp

View File

@ -1,139 +0,0 @@
//===- llvm/unittest/XRay/FDRBlockVerifierTest.cpp --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Testing/Support/Error.h"
#include "llvm/XRay/BlockIndexer.h"
#include "llvm/XRay/BlockVerifier.h"
#include "llvm/XRay/FDRLogBuilder.h"
#include "llvm/XRay/FDRRecords.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace llvm {
namespace xray {
namespace {
using ::testing::ElementsAre;
using ::testing::Not;
using ::testing::SizeIs;
TEST(FDRBlockVerifierTest, ValidBlocksV3) {
auto Block0 = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
auto Block1 = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
auto Block2 = LogBuilder()
.add<BufferExtents>(80)
.add<NewBufferRecord>(2)
.add<WallclockRecord>(1, 2)
.add<PIDRecord>(1)
.add<NewCPUIDRecord>(2)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockIndexer::Index Index;
BlockIndexer Indexer(Index);
for (auto B : {std::ref(Block0), std::ref(Block1), std::ref(Block2)}) {
for (auto &R : B.get())
ASSERT_FALSE(errorToBool(R->apply(Indexer)));
ASSERT_FALSE(errorToBool(Indexer.flush()));
}
BlockVerifier Verifier;
for (auto &ProcessThreadBlocks : Index) {
auto &Blocks = ProcessThreadBlocks.second;
for (auto &B : Blocks) {
for (auto *R : B.Records)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
Verifier.reset();
}
}
}
TEST(FDRBlockVerifierTest, MissingPIDRecord) {
auto Block = LogBuilder()
.add<BufferExtents>(20)
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockVerifier Verifier;
for (auto &R : Block)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
}
TEST(FDRBlockVerifierTest, MissingBufferExtents) {
auto Block = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockVerifier Verifier;
for (auto &R : Block)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
}
TEST(FDRBlockVerifierTest, IgnoreRecordsAfterEOB) {
auto Block = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<EndBufferRecord>()
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.consume();
BlockVerifier Verifier;
for (auto &R : Block)
ASSERT_FALSE(errorToBool(R->apply(Verifier)));
ASSERT_FALSE(errorToBool(Verifier.verify()));
}
TEST(FDRBlockVerifierTest, MalformedV2) {
auto Block = LogBuilder()
.add<NewBufferRecord>(1)
.add<WallclockRecord>(1, 2)
.add<NewCPUIDRecord>(1)
.add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
.add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
.add<NewBufferRecord>(2)
.consume();
BlockVerifier Verifier;
ASSERT_THAT(Block, SizeIs(6u));
EXPECT_THAT_ERROR(Block[0]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[1]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[2]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[3]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[4]->apply(Verifier), Succeeded());
EXPECT_THAT_ERROR(Block[5]->apply(Verifier), Failed());
}
} // namespace
} // namespace xray
} // namespace llvm