1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00
llvm-mirror/utils/TableGen/PredicateExpander.h
Andrea Di Biagio b2b609ef71 [tblgen][PredicateExpander] Add the ability to describe more complex constraints on instruction operands.
Before this patch, class PredicateExpander only knew how to expand simple
predicates that performed checks on instruction operands.
In particular, the new scheduling predicate syntax was not rich enough to
express checks like this one:

  Foo(MI->getOperand(0).getImm()) == ExpectedVal;

Here, the immediate operand value at index zero is passed in input to function
Foo, and ExpectedVal is compared against the value returned by function Foo.

While this predicate pattern doesn't show up in any X86 model, it shows up in
other upstream targets. So, being able to support those predicates is
fundamental if we want to be able to modernize all the scheduling models
upstream.

With this patch, we allow users to specify if a register/immediate operand value
needs to be passed in input to a function as part of the predicate check. Now,
register/immediate operand checks all derive from base class CheckOperandBase.

This patch also changes where TIIPredicate definitions are expanded by the
instructon info emitter. Before, definitions were expanded in class
XXXGenInstrInfo (where XXX is a target name).
With the introduction of this new syntax, we may want to have TIIPredicates
expanded directly in XXXInstrInfo. That is because functions used by the new
operand predicates may only exist in the derived class (i.e. XXXInstrInfo).

This patch is a non functional change for the existing scheduling models.
In future, we will be able to use this richer syntax to better describe complex
scheduling predicates, and expose them to llvm-mca.

Differential Revision: https://reviews.llvm.org/D53880

llvm-svn: 345714
2018-10-31 12:28:05 +00:00

125 lines
5.2 KiB
C++

//===--------------------- PredicateExpander.h ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// Functionalities used by the Tablegen backends to expand machine predicates.
///
/// See file llvm/Target/TargetInstrPredicate.td for a full list and description
/// of all the supported MCInstPredicate classes.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UTILS_TABLEGEN_PREDICATEEXPANDER_H
#define LLVM_UTILS_TABLEGEN_PREDICATEEXPANDER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
namespace llvm {
class raw_ostream;
class PredicateExpander {
bool EmitCallsByRef;
bool NegatePredicate;
bool ExpandForMC;
unsigned IndentLevel;
StringRef TargetName;
PredicateExpander(const PredicateExpander &) = delete;
PredicateExpander &operator=(const PredicateExpander &) = delete;
public:
PredicateExpander(StringRef Target)
: EmitCallsByRef(true), NegatePredicate(false), ExpandForMC(false),
IndentLevel(1U), TargetName(Target) {}
bool isByRef() const { return EmitCallsByRef; }
bool shouldNegate() const { return NegatePredicate; }
bool shouldExpandForMC() const { return ExpandForMC; }
unsigned getIndentLevel() const { return IndentLevel; }
StringRef getTargetName() const { return TargetName; }
void setByRef(bool Value) { EmitCallsByRef = Value; }
void flipNegatePredicate() { NegatePredicate = !NegatePredicate; }
void setNegatePredicate(bool Value) { NegatePredicate = Value; }
void setExpandForMC(bool Value) { ExpandForMC = Value; }
void setIndentLevel(unsigned Level) { IndentLevel = Level; }
void increaseIndentLevel() { ++IndentLevel; }
void decreaseIndentLevel() { --IndentLevel; }
using RecVec = std::vector<Record *>;
void expandTrue(raw_ostream &OS);
void expandFalse(raw_ostream &OS);
void expandCheckImmOperand(raw_ostream &OS, int OpIndex, int ImmVal,
StringRef FunctionMapper);
void expandCheckImmOperand(raw_ostream &OS, int OpIndex, StringRef ImmVal,
StringRef FunctionMapperer);
void expandCheckImmOperandSimple(raw_ostream &OS, int OpIndex,
StringRef FunctionMapper);
void expandCheckRegOperand(raw_ostream &OS, int OpIndex, const Record *Reg,
StringRef FunctionMapper);
void expandCheckRegOperandSimple(raw_ostream &OS, int OpIndex,
StringRef FunctionMapper);
void expandCheckSameRegOperand(raw_ostream &OS, int First, int Second);
void expandCheckNumOperands(raw_ostream &OS, int NumOps);
void expandCheckOpcode(raw_ostream &OS, const Record *Inst);
void expandCheckPseudo(raw_ostream &OS, const RecVec &Opcodes);
void expandCheckOpcode(raw_ostream &OS, const RecVec &Opcodes);
void expandPredicateSequence(raw_ostream &OS, const RecVec &Sequence,
bool IsCheckAll);
void expandTIIFunctionCall(raw_ostream &OS, StringRef MethodName);
void expandCheckIsRegOperand(raw_ostream &OS, int OpIndex);
void expandCheckIsImmOperand(raw_ostream &OS, int OpIndex);
void expandCheckInvalidRegOperand(raw_ostream &OS, int OpIndex);
void expandCheckFunctionPredicate(raw_ostream &OS, StringRef MCInstFn,
StringRef MachineInstrFn);
void expandCheckNonPortable(raw_ostream &OS, StringRef CodeBlock);
void expandPredicate(raw_ostream &OS, const Record *Rec);
void expandReturnStatement(raw_ostream &OS, const Record *Rec);
void expandOpcodeSwitchCase(raw_ostream &OS, const Record *Rec);
void expandOpcodeSwitchStatement(raw_ostream &OS, const RecVec &Cases,
const Record *Default);
void expandStatement(raw_ostream &OS, const Record *Rec);
};
// Forward declarations.
class STIPredicateFunction;
class OpcodeGroup;
class STIPredicateExpander : public PredicateExpander {
StringRef ClassPrefix;
bool ExpandDefinition;
STIPredicateExpander(const PredicateExpander &) = delete;
STIPredicateExpander &operator=(const PredicateExpander &) = delete;
void expandHeader(raw_ostream &OS, const STIPredicateFunction &Fn);
void expandPrologue(raw_ostream &OS, const STIPredicateFunction &Fn);
void expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
bool ShouldUpdateOpcodeMask);
void expandBody(raw_ostream &OS, const STIPredicateFunction &Fn);
void expandEpilogue(raw_ostream &OS, const STIPredicateFunction &Fn);
public:
STIPredicateExpander(StringRef Target)
: PredicateExpander(Target), ClassPrefix(), ExpandDefinition(false) {}
bool shouldExpandDefinition() const { return ExpandDefinition; }
StringRef getClassPrefix() const { return ClassPrefix; }
void setClassPrefix(StringRef S) { ClassPrefix = S; }
void setExpandDefinition(bool Value) { ExpandDefinition = Value; }
void expandSTIPredicate(raw_ostream &OS, const STIPredicateFunction &Fn);
};
} // namespace llvm
#endif