[llvm] r291069 - IR: Module summary representation for type identifiers; summary test scaffolding for lowertypetests.
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 4 19:39:01 PST 2017
Author: pcc
Date: Wed Jan 4 21:39:00 2017
New Revision: 291069
URL: http://llvm.org/viewvc/llvm-project?rev=291069&view=rev
Log:
IR: Module summary representation for type identifiers; summary test scaffolding for lowertypetests.
Set up basic YAML I/O support for module summaries, plumb the summary into
the pass and add a few command line flags to test YAML I/O support. Bitcode
support to come separately, as will the code in LowerTypeTests that actually
uses the summary. Also add a couple of tests that pass by virtue of the pass
doing nothing with the summary (which happens to be the correct thing to do
for those tests).
Differential Revision: https://reviews.llvm.org/D28041
Added:
llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h
llvm/trunk/test/Transforms/LowerTypeTests/Inputs/
llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-unsat.yaml
llvm/trunk/test/Transforms/LowerTypeTests/export-nothing.ll
llvm/trunk/test/Transforms/LowerTypeTests/import-unsat.ll
Modified:
llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp
Modified: llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h?rev=291069&r1=291068&r2=291069&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h (original)
+++ llvm/trunk/include/llvm/IR/ModuleSummaryIndex.h Wed Jan 4 21:39:00 2017
@@ -28,6 +28,10 @@
namespace llvm {
+namespace yaml {
+template <typename T> struct MappingTraits;
+}
+
/// \brief Class to accumulate and hold information about a callee.
struct CalleeInfo {
enum class HotnessType : uint8_t { Unknown = 0, Cold = 1, None = 2, Hot = 3 };
@@ -330,6 +334,30 @@ public:
}
};
+struct TypeTestResolution {
+ /// Specifies which kind of type check we should emit for this byte array.
+ /// See http://clang.llvm.org/docs/ControlFlowIntegrityDesign.html for full
+ /// details on each kind of check; the enumerators are described with
+ /// reference to that document.
+ enum Kind {
+ Unsat, ///< Unsatisfiable type (i.e. no global has this type metadata)
+ ByteArray, ///< Test a byte array (first example)
+ Inline, ///< Inlined bit vector ("Short Inline Bit Vectors")
+ Single, ///< Single element (last example in "Short Inline Bit Vectors")
+ AllOnes, ///< All-ones bit vector ("Eliminating Bit Vector Checks for
+ /// All-Ones Bit Vectors")
+ } TheKind = Unsat;
+
+ /// Range of the size expressed as a bit width. For example, if the size is in
+ /// range [0,256), this number will be 8. This helps generate the most compact
+ /// instruction sequences.
+ unsigned SizeBitWidth = 0;
+};
+
+struct TypeIdSummary {
+ TypeTestResolution TTRes;
+};
+
/// 160 bits SHA1
typedef std::array<uint32_t, 5> ModuleHash;
@@ -370,6 +398,14 @@ private:
/// Holds strings for combined index, mapping to the corresponding module ID.
ModulePathStringTableTy ModulePathStringTable;
+ /// Mapping from type identifiers to summary information for that type
+ /// identifier.
+ // FIXME: Add bitcode read/write support for this field.
+ std::map<std::string, TypeIdSummary> TypeIdMap;
+
+ // YAML I/O support.
+ friend yaml::MappingTraits<ModuleSummaryIndex>;
+
public:
gvsummary_iterator begin() { return GlobalValueMap.begin(); }
const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
Added: llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h?rev=291069&view=auto
==============================================================================
--- llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h (added)
+++ llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h Wed Jan 4 21:39:00 2017
@@ -0,0 +1,111 @@
+//===-- llvm/ModuleSummaryIndexYAML.h - YAML I/O for summary ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_MODULESUMMARYINDEXYAML_H
+#define LLVM_IR_MODULESUMMARYINDEXYAML_H
+
+#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/Support/YAMLTraits.h"
+
+namespace llvm {
+namespace yaml {
+
+template <> struct ScalarEnumerationTraits<TypeTestResolution::Kind> {
+ static void enumeration(IO &io, TypeTestResolution::Kind &value) {
+ io.enumCase(value, "Unsat", TypeTestResolution::Unsat);
+ io.enumCase(value, "ByteArray", TypeTestResolution::ByteArray);
+ io.enumCase(value, "Inline", TypeTestResolution::Inline);
+ io.enumCase(value, "Single", TypeTestResolution::Single);
+ io.enumCase(value, "AllOnes", TypeTestResolution::AllOnes);
+ }
+};
+
+template <> struct MappingTraits<TypeTestResolution> {
+ static void mapping(IO &io, TypeTestResolution &res) {
+ io.mapRequired("Kind", res.TheKind);
+ io.mapRequired("SizeBitWidth", res.SizeBitWidth);
+ }
+};
+
+template <> struct MappingTraits<TypeIdSummary> {
+ static void mapping(IO &io, TypeIdSummary& summary) {
+ io.mapRequired("TTRes", summary.TTRes);
+ }
+};
+
+struct FunctionSummaryYaml {
+ std::vector<uint64_t> TypeTests;
+};
+
+} // End yaml namespace
+} // End llvm namespace
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(uint64_t)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<FunctionSummaryYaml> {
+ static void mapping(IO &io, FunctionSummaryYaml& summary) {
+ io.mapRequired("TypeTests", summary.TypeTests);
+ }
+};
+
+} // End yaml namespace
+} // End llvm namespace
+
+LLVM_YAML_IS_STRING_MAP(TypeIdSummary)
+LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml)
+
+namespace llvm {
+namespace yaml {
+
+// FIXME: Add YAML mappings for the rest of the module summary.
+template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
+ static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V) {
+ std::vector<FunctionSummaryYaml> FSums;
+ io.mapRequired(Key.str().c_str(), FSums);
+ uint64_t KeyInt;
+ if (Key.getAsInteger(0, KeyInt)) {
+ io.setError("key not an integer");
+ return;
+ }
+ auto &Elem = V[KeyInt];
+ for (auto &FSum : FSums) {
+ GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,
+ false, false);
+ Elem.push_back(make_unique<FunctionSummary>(
+ GVFlags, 0, ArrayRef<ValueInfo>{},
+ ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests)));
+ }
+ }
+ static void output(IO &io, GlobalValueSummaryMapTy &V) {
+ for (auto &P : V) {
+ std::vector<FunctionSummaryYaml> FSums;
+ for (auto &Sum : P.second) {
+ if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get()))
+ FSums.push_back(FunctionSummaryYaml{FSum->type_tests()});
+ }
+ if (!FSums.empty())
+ io.mapRequired(std::to_string(P.first).c_str(), FSums);
+ }
+ }
+};
+
+template <> struct MappingTraits<ModuleSummaryIndex> {
+ static void mapping(IO &io, ModuleSummaryIndex& index) {
+ io.mapRequired("GlobalValueMap", index.GlobalValueMap);
+ io.mapRequired("TypeIdMap", index.TypeIdMap);
+ }
+};
+
+} // End yaml namespace
+} // End llvm namespace
+
+#endif
Modified: llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp?rev=291069&r1=291068&r2=291069&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp Wed Jan 4 21:39:00 2017
@@ -27,9 +27,12 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/ModuleSummaryIndexYAML.h"
#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TrailingObjects.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
@@ -52,6 +55,20 @@ static cl::opt<bool> AvoidReuse(
cl::desc("Try to avoid reuse of byte array addresses using aliases"),
cl::Hidden, cl::init(true));
+static cl::opt<std::string> ClSummaryAction(
+ "lowertypetests-summary-action",
+ cl::desc("What to do with the summary when running this pass"), cl::Hidden);
+
+static cl::opt<std::string> ClReadSummary(
+ "lowertypetests-read-summary",
+ cl::desc("Read summary from given YAML file before running pass"),
+ cl::Hidden);
+
+static cl::opt<std::string> ClWriteSummary(
+ "lowertypetests-write-summary",
+ cl::desc("Write summary to given YAML file after running pass"),
+ cl::Hidden);
+
bool BitSetInfo::containsGlobalOffset(uint64_t Offset) const {
if (Offset < ByteOffset)
return false;
@@ -241,6 +258,9 @@ public:
class LowerTypeTestsModule {
Module &M;
+ // This is for testing purposes only.
+ std::unique_ptr<ModuleSummaryIndex> OwnedSummary;
+
bool LinkerSubsectionsViaSymbols;
Triple::ArchType Arch;
Triple::OSType OS;
@@ -302,6 +322,7 @@ class LowerTypeTestsModule {
public:
LowerTypeTestsModule(Module &M);
+ ~LowerTypeTestsModule();
bool lower();
};
@@ -1080,6 +1101,22 @@ void LowerTypeTestsModule::buildBitSetsF
/// Lower all type tests in this module.
LowerTypeTestsModule::LowerTypeTestsModule(Module &M) : M(M) {
+ // Handle the command-line summary arguments. This code is for testing
+ // purposes only, so we handle errors directly.
+ if (!ClSummaryAction.empty()) {
+ OwnedSummary = make_unique<ModuleSummaryIndex>();
+ if (!ClReadSummary.empty()) {
+ ExitOnError ExitOnErr("-lowertypetests-read-summary: " + ClReadSummary +
+ ": ");
+ auto ReadSummaryFile =
+ ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(ClReadSummary)));
+
+ yaml::Input In(ReadSummaryFile->getBuffer());
+ In >> *OwnedSummary;
+ ExitOnErr(errorCodeToError(In.error()));
+ }
+ }
+
Triple TargetTriple(M.getTargetTriple());
LinkerSubsectionsViaSymbols = TargetTriple.isMacOSX();
Arch = TargetTriple.getArch();
@@ -1087,6 +1124,20 @@ LowerTypeTestsModule::LowerTypeTestsModu
ObjectFormat = TargetTriple.getObjectFormat();
}
+LowerTypeTestsModule::~LowerTypeTestsModule() {
+ if (ClSummaryAction.empty() || ClWriteSummary.empty())
+ return;
+
+ ExitOnError ExitOnErr("-lowertypetests-write-summary: " + ClWriteSummary +
+ ": ");
+ std::error_code EC;
+ raw_fd_ostream OS(ClWriteSummary, EC, sys::fs::F_Text);
+ ExitOnErr(errorCodeToError(EC));
+
+ yaml::Output Out(OS);
+ Out << *OwnedSummary;
+}
+
bool LowerTypeTestsModule::lower() {
Function *TypeTestFunc =
M.getFunction(Intrinsic::getName(Intrinsic::type_test));
Added: llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-unsat.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-unsat.yaml?rev=291069&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-unsat.yaml (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-unsat.yaml Wed Jan 4 21:39:00 2017
@@ -0,0 +1,10 @@
+---
+GlobalValueMap:
+ 42:
+ - TypeTests: [123]
+TypeIdMap:
+ typeid1:
+ TTRes:
+ Kind: Unsat
+ SizeBitWidth: 0
+...
Added: llvm/trunk/test/Transforms/LowerTypeTests/export-nothing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/export-nothing.ll?rev=291069&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/export-nothing.ll (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/export-nothing.ll Wed Jan 4 21:39:00 2017
@@ -0,0 +1,7 @@
+; RUN: opt -lowertypetests -lowertypetests-summary-action=export -lowertypetests-write-summary=%t -o /dev/null %s
+; RUN: FileCheck %s < %t
+
+; CHECK: ---
+; CHECK-NEXT: GlobalValueMap:
+; CHECK-NEXT: TypeIdMap:
+; CHECK-NEXT: ...
Added: llvm/trunk/test/Transforms/LowerTypeTests/import-unsat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/import-unsat.ll?rev=291069&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/import-unsat.ll (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/import-unsat.ll Wed Jan 4 21:39:00 2017
@@ -0,0 +1,24 @@
+; Test that we correctly import an unsat resolution for type identifier "typeid1".
+; FIXME: We should not require -O2 to simplify this to return false.
+; RUN: opt -S -lowertypetests -lowertypetests-summary-action=import -lowertypetests-read-summary=%S/Inputs/import-unsat.yaml -lowertypetests-write-summary=%t -O2 < %s | FileCheck %s
+; RUN: FileCheck --check-prefix=SUMMARY %s < %t
+
+; SUMMARY: GlobalValueMap:
+; SUMMARY-NEXT: 42:
+; SUMMARY-NEXT: - TypeTests:
+; SUMMARY-NEXT: - 123
+; SUMMARY-NEXT: TypeIdMap:
+; SUMMARY-NEXT: typeid1:
+; SUMMARY-NEXT: TTRes:
+; SUMMARY-NEXT: Kind: Unsat
+; SUMMARY-NEXT: SizeBitWidth: 0
+
+target datalayout = "e-p:32:32"
+
+declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
+
+define i1 @foo(i8* %p) {
+ %x = call i1 @llvm.type.test(i8* %p, metadata !"typeid1")
+ ; CHECK: ret i1 false
+ ret i1 %x
+}
More information about the llvm-commits
mailing list