2011-10-01 16:41:13 +00:00
|
|
|
//===- llvm/TableGen/Record.h - Classes for Table Records -------*- C++ -*-===//
|
2005-04-22 00:00:37 +00:00
|
|
|
//
|
2003-10-20 20:20:30 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:37:13 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-22 00:00:37 +00:00
|
|
|
//
|
2003-10-20 20:20:30 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2002-12-02 01:23:04 +00:00
|
|
|
//
|
2003-07-31 04:37:57 +00:00
|
|
|
// This file defines the main TableGen data structures, including the TableGen
|
|
|
|
// types, values, and high-level data structures.
|
2002-12-02 01:23:04 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-10-01 16:41:13 +00:00
|
|
|
#ifndef LLVM_TABLEGEN_RECORD_H
|
|
|
|
#define LLVM_TABLEGEN_RECORD_H
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-07-29 19:06:59 +00:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
2011-07-29 19:07:11 +00:00
|
|
|
#include "llvm/ADT/FoldingSet.h"
|
2011-07-29 19:07:07 +00:00
|
|
|
#include "llvm/Support/Allocator.h"
|
2012-10-05 03:31:56 +00:00
|
|
|
#include "llvm/Support/Casting.h"
|
2010-11-29 18:47:54 +00:00
|
|
|
#include "llvm/Support/DataTypes.h"
|
2012-02-05 22:14:15 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2012-12-03 17:02:12 +00:00
|
|
|
#include "llvm/Support/SourceMgr.h"
|
2009-07-03 00:10:29 +00:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2002-12-02 01:23:04 +00:00
|
|
|
#include <map>
|
2003-06-11 14:17:21 +00:00
|
|
|
|
2003-11-11 22:41:34 +00:00
|
|
|
namespace llvm {
|
2009-07-03 00:10:29 +00:00
|
|
|
class raw_ostream;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2005-04-19 03:36:21 +00:00
|
|
|
// RecTy subclasses.
|
2003-08-03 18:17:22 +00:00
|
|
|
class BitRecTy;
|
|
|
|
class BitsRecTy;
|
|
|
|
class IntRecTy;
|
|
|
|
class StringRecTy;
|
|
|
|
class ListRecTy;
|
2003-08-04 04:50:57 +00:00
|
|
|
class DagRecTy;
|
2003-08-03 18:17:22 +00:00
|
|
|
class RecordRecTy;
|
|
|
|
|
2005-04-19 03:36:21 +00:00
|
|
|
// Init subclasses.
|
2011-07-13 22:25:51 +00:00
|
|
|
class Init;
|
2002-12-02 01:23:04 +00:00
|
|
|
class UnsetInit;
|
|
|
|
class BitInit;
|
|
|
|
class BitsInit;
|
|
|
|
class IntInit;
|
|
|
|
class StringInit;
|
|
|
|
class ListInit;
|
2009-05-14 21:22:49 +00:00
|
|
|
class UnOpInit;
|
2006-03-31 21:53:49 +00:00
|
|
|
class BinOpInit;
|
2009-05-14 21:54:42 +00:00
|
|
|
class TernOpInit;
|
2002-12-02 01:23:04 +00:00
|
|
|
class DefInit;
|
2003-08-04 20:44:17 +00:00
|
|
|
class DagInit;
|
2002-12-02 17:53:54 +00:00
|
|
|
class TypedInit;
|
|
|
|
class VarInit;
|
2002-12-02 16:42:52 +00:00
|
|
|
class FieldInit;
|
2002-12-02 17:53:54 +00:00
|
|
|
class VarBitInit;
|
2004-07-27 01:01:21 +00:00
|
|
|
class VarListElementInit;
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2005-04-19 03:36:21 +00:00
|
|
|
// Other classes.
|
2002-12-02 01:23:04 +00:00
|
|
|
class Record;
|
2005-04-19 03:36:21 +00:00
|
|
|
class RecordVal;
|
2009-04-30 17:35:11 +00:00
|
|
|
struct MultiClass;
|
2010-12-13 00:23:57 +00:00
|
|
|
class RecordKeeper;
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Type Classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
class RecTy {
|
2012-10-05 03:31:56 +00:00
|
|
|
public:
|
|
|
|
/// \brief Subclass discriminator (for dyn_cast<> et al.)
|
|
|
|
enum RecTyKind {
|
|
|
|
BitRecTyKind,
|
|
|
|
BitsRecTyKind,
|
|
|
|
IntRecTyKind,
|
|
|
|
StringRecTyKind,
|
|
|
|
ListRecTyKind,
|
|
|
|
DagRecTyKind,
|
|
|
|
RecordRecTyKind
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
RecTyKind Kind;
|
2011-07-18 17:02:57 +00:00
|
|
|
ListRecTy *ListTy;
|
2011-12-20 02:50:00 +00:00
|
|
|
virtual void anchor();
|
2012-10-05 03:31:56 +00:00
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
RecTyKind getRecTyKind() const { return Kind; }
|
|
|
|
|
|
|
|
RecTy(RecTyKind K) : Kind(K), ListTy(0) {}
|
2002-12-02 01:23:04 +00:00
|
|
|
virtual ~RecTy() {}
|
|
|
|
|
2007-11-20 22:25:16 +00:00
|
|
|
virtual std::string getAsString() const = 0;
|
2009-07-03 00:10:29 +00:00
|
|
|
void print(raw_ostream &OS) const { OS << getAsString(); }
|
2003-08-03 18:17:22 +00:00
|
|
|
void dump() const;
|
|
|
|
|
|
|
|
/// typeIsConvertibleTo - Return true if all values of 'this' type can be
|
|
|
|
/// converted to the specified type.
|
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
/// getListTy - Returns the type representing list<this>.
|
|
|
|
ListRecTy *getListTy();
|
|
|
|
|
2003-08-03 18:17:22 +00:00
|
|
|
public: // These methods should only be called from subclasses of Init
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return 0; }
|
|
|
|
virtual Init *convertValue( BitInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( BitsInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( IntInit *II) { return 0; }
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *UI) {
|
|
|
|
return convertValue((TypedInit*)UI);
|
2009-05-14 21:22:49 +00:00
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( BinOpInit *UI) {
|
|
|
|
return convertValue((TypedInit*)UI);
|
2009-04-23 21:25:15 +00:00
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( TernOpInit *UI) {
|
|
|
|
return convertValue((TypedInit*)UI);
|
2009-05-14 21:54:42 +00:00
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( TypedInit *TI) { return 0; }
|
|
|
|
virtual Init *convertValue( VarInit *VI) {
|
|
|
|
return convertValue((TypedInit*)VI);
|
2002-12-02 17:53:54 +00:00
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( FieldInit *FI) {
|
|
|
|
return convertValue((TypedInit*)FI);
|
2002-12-02 17:53:54 +00:00
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2013-01-07 02:30:19 +00:00
|
|
|
public:
|
|
|
|
virtual bool baseClassOf(const RecTy*) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2009-07-03 00:10:29 +00:00
|
|
|
inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) {
|
2002-12-02 01:23:04 +00:00
|
|
|
Ty.print(OS);
|
|
|
|
return OS;
|
|
|
|
}
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// BitRecTy - 'bit' - Represent a single bit
|
|
|
|
///
|
2004-10-27 16:14:51 +00:00
|
|
|
class BitRecTy : public RecTy {
|
2011-07-18 17:02:57 +00:00
|
|
|
static BitRecTy Shared;
|
2012-10-05 03:31:56 +00:00
|
|
|
BitRecTy() : RecTy(BitRecTyKind) {}
|
2004-10-27 16:14:51 +00:00
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == BitRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static BitRecTy *get() { return &Shared; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
|
|
|
|
virtual Init *convertValue( BitInit *BI) { return (Init*)BI; }
|
|
|
|
virtual Init *convertValue( BitsInit *BI);
|
|
|
|
virtual Init *convertValue( IntInit *II);
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TypedInit *TI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const { return "bit"; }
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
2013-01-07 02:30:19 +00:00
|
|
|
virtual bool baseClassOf(const RecTy*) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
2013-02-05 16:40:22 +00:00
|
|
|
/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
|
2002-12-02 16:13:23 +00:00
|
|
|
///
|
2002-12-02 01:23:04 +00:00
|
|
|
class BitsRecTy : public RecTy {
|
|
|
|
unsigned Size;
|
2012-10-05 03:31:56 +00:00
|
|
|
explicit BitsRecTy(unsigned Sz) : RecTy(BitsRecTyKind), Size(Sz) {}
|
2011-07-18 17:02:57 +00:00
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == BitsRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static BitsRecTy *get(unsigned Sz);
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
unsigned getNumBits() const { return Size; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI);
|
|
|
|
virtual Init *convertValue( BitInit *UI);
|
|
|
|
virtual Init *convertValue( BitsInit *BI);
|
|
|
|
virtual Init *convertValue( IntInit *II);
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TypedInit *TI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2004-12-06 23:42:37 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const;
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
2013-01-07 02:30:19 +00:00
|
|
|
virtual bool baseClassOf(const RecTy*) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// IntRecTy - 'int' - Represent an integer value of no particular size
|
|
|
|
///
|
2004-10-27 16:14:51 +00:00
|
|
|
class IntRecTy : public RecTy {
|
2011-07-18 17:02:57 +00:00
|
|
|
static IntRecTy Shared;
|
2012-10-05 03:31:56 +00:00
|
|
|
IntRecTy() : RecTy(IntRecTyKind) {}
|
2004-10-27 16:14:51 +00:00
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == IntRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static IntRecTy *get() { return &Shared; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
|
|
|
|
virtual Init *convertValue( BitInit *BI);
|
|
|
|
virtual Init *convertValue( BitsInit *BI);
|
|
|
|
virtual Init *convertValue( IntInit *II) { return (Init*)II; }
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TypedInit *TI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2004-12-06 23:42:37 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const { return "int"; }
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
|
|
|
|
2013-01-07 02:30:19 +00:00
|
|
|
virtual bool baseClassOf(const RecTy*) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
/// StringRecTy - 'string' - Represent an string value
|
|
|
|
///
|
2004-10-27 16:14:51 +00:00
|
|
|
class StringRecTy : public RecTy {
|
2011-07-18 17:02:57 +00:00
|
|
|
static StringRecTy Shared;
|
2012-10-05 03:31:56 +00:00
|
|
|
StringRecTy() : RecTy(StringRecTyKind) {}
|
2004-10-27 16:14:51 +00:00
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == StringRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static StringRecTy *get() { return &Shared; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
|
|
|
|
virtual Init *convertValue( BitInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( BitsInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( IntInit *II) { return 0; }
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *BO);
|
|
|
|
virtual Init *convertValue( BinOpInit *BO);
|
|
|
|
virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
|
|
|
|
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( TypedInit *TI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2004-12-06 23:42:37 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const { return "string"; }
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2013-02-05 16:40:22 +00:00
|
|
|
/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
|
|
|
|
/// the specified type.
|
2002-12-02 16:13:23 +00:00
|
|
|
///
|
2002-12-02 01:23:04 +00:00
|
|
|
class ListRecTy : public RecTy {
|
2003-08-03 18:17:22 +00:00
|
|
|
RecTy *Ty;
|
2012-10-05 03:31:56 +00:00
|
|
|
explicit ListRecTy(RecTy *T) : RecTy(ListRecTyKind), Ty(T) {}
|
2011-07-18 17:02:57 +00:00
|
|
|
friend ListRecTy *RecTy::getListTy();
|
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == ListRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static ListRecTy *get(RecTy *T) { return T->getListTy(); }
|
2003-08-03 18:17:22 +00:00
|
|
|
RecTy *getElementType() const { return Ty; }
|
2003-07-30 04:16:52 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
|
|
|
|
virtual Init *convertValue( BitInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( BitsInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( IntInit *II) { return 0; }
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI);
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TypedInit *TI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const;
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
|
|
|
|
2013-01-07 02:30:19 +00:00
|
|
|
virtual bool baseClassOf(const RecTy*) const;
|
2003-07-30 21:47:42 +00:00
|
|
|
};
|
|
|
|
|
2003-08-04 04:50:57 +00:00
|
|
|
/// DagRecTy - 'dag' - Represent a dag fragment
|
|
|
|
///
|
2004-10-27 16:14:51 +00:00
|
|
|
class DagRecTy : public RecTy {
|
2011-07-18 17:02:57 +00:00
|
|
|
static DagRecTy Shared;
|
2012-10-05 03:31:56 +00:00
|
|
|
DagRecTy() : RecTy(DagRecTyKind) {}
|
2004-10-27 16:14:51 +00:00
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == DagRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static DagRecTy *get() { return &Shared; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
|
|
|
|
virtual Init *convertValue( BitInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( BitsInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( IntInit *II) { return 0; }
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( DefInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *BO);
|
|
|
|
virtual Init *convertValue( BinOpInit *BO);
|
|
|
|
virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
|
|
|
|
virtual Init *convertValue( DagInit *CI) { return (Init*)CI; }
|
|
|
|
virtual Init *convertValue( TypedInit *TI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2003-08-04 04:50:57 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const { return "dag"; }
|
2003-08-04 04:50:57 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-04 04:50:57 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2003-07-30 21:47:42 +00:00
|
|
|
|
2004-04-15 15:30:15 +00:00
|
|
|
/// RecordRecTy - '[classname]' - Represent an instance of a class, such as:
|
2002-12-02 16:13:23 +00:00
|
|
|
/// (R32 X = EAX).
|
|
|
|
///
|
2002-12-02 01:23:04 +00:00
|
|
|
class RecordRecTy : public RecTy {
|
|
|
|
Record *Rec;
|
2012-10-05 03:31:56 +00:00
|
|
|
explicit RecordRecTy(Record *R) : RecTy(RecordRecTyKind), Rec(R) {}
|
2011-07-18 17:02:57 +00:00
|
|
|
friend class Record;
|
|
|
|
public:
|
2012-10-05 03:31:56 +00:00
|
|
|
static bool classof(const RecTy *RT) {
|
|
|
|
return RT->getRecTyKind() == RecordRecTyKind;
|
|
|
|
}
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
static RecordRecTy *get(Record *R);
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2002-12-02 16:42:52 +00:00
|
|
|
Record *getRecord() const { return Rec; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; }
|
|
|
|
virtual Init *convertValue( BitInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( BitsInit *BI) { return 0; }
|
|
|
|
virtual Init *convertValue( IntInit *II) { return 0; }
|
|
|
|
virtual Init *convertValue(StringInit *SI) { return 0; }
|
|
|
|
virtual Init *convertValue( ListInit *LI) { return 0; }
|
|
|
|
virtual Init *convertValue(VarBitInit *VB) { return 0; }
|
|
|
|
virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
|
|
|
|
virtual Init *convertValue( DefInit *DI);
|
|
|
|
virtual Init *convertValue( DagInit *DI) { return 0; }
|
|
|
|
virtual Init *convertValue( TypedInit *VI);
|
|
|
|
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
|
|
|
|
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual std::string getAsString() const;
|
2003-08-03 18:17:22 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual bool typeIsConvertibleTo(const RecTy *RHS) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
return RHS->baseClassOf(this);
|
|
|
|
}
|
2013-01-07 02:30:19 +00:00
|
|
|
virtual bool baseClassOf(const RecTy*) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2009-11-22 04:24:42 +00:00
|
|
|
/// resolveTypes - Find a common type that T1 and T2 convert to.
|
2009-06-08 20:23:18 +00:00
|
|
|
/// Return 0 if no such type exists.
|
|
|
|
///
|
|
|
|
RecTy *resolveTypes(RecTy *T1, RecTy *T2);
|
2002-12-02 16:13:23 +00:00
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Initializer Classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-07-13 22:25:51 +00:00
|
|
|
class Init {
|
2012-10-10 20:24:40 +00:00
|
|
|
protected:
|
|
|
|
/// \brief Discriminator enum (for isa<>, dyn_cast<>, et al.)
|
|
|
|
///
|
|
|
|
/// This enum is laid out by a preorder traversal of the inheritance
|
|
|
|
/// hierarchy, and does not contain an entry for abstract classes, as per
|
|
|
|
/// the recommendation in docs/HowToSetUpLLVMStyleRTTI.rst.
|
|
|
|
///
|
|
|
|
/// We also explicitly include "first" and "last" values for each
|
|
|
|
/// interior node of the inheritance tree, to make it easier to read the
|
|
|
|
/// corresponding classof().
|
|
|
|
///
|
|
|
|
/// We could pack these a bit tighter by not having the IK_FirstXXXInit
|
|
|
|
/// and IK_LastXXXInit be their own values, but that would degrade
|
|
|
|
/// readability for really no benefit.
|
|
|
|
enum InitKind {
|
|
|
|
IK_BitInit,
|
|
|
|
IK_BitsInit,
|
|
|
|
IK_FirstTypedInit,
|
|
|
|
IK_DagInit,
|
|
|
|
IK_DefInit,
|
|
|
|
IK_FieldInit,
|
|
|
|
IK_IntInit,
|
|
|
|
IK_ListInit,
|
|
|
|
IK_FirstOpInit,
|
|
|
|
IK_BinOpInit,
|
|
|
|
IK_TernOpInit,
|
|
|
|
IK_UnOpInit,
|
|
|
|
IK_LastOpInit,
|
|
|
|
IK_StringInit,
|
|
|
|
IK_VarInit,
|
|
|
|
IK_VarListElementInit,
|
|
|
|
IK_LastTypedInit,
|
|
|
|
IK_UnsetInit,
|
|
|
|
IK_VarBitInit
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
const InitKind Kind;
|
2012-09-16 21:43:09 +00:00
|
|
|
Init(const Init &) LLVM_DELETED_FUNCTION;
|
|
|
|
Init &operator=(const Init &) LLVM_DELETED_FUNCTION;
|
2011-12-20 02:50:00 +00:00
|
|
|
virtual void anchor();
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-10-10 20:24:40 +00:00
|
|
|
public:
|
|
|
|
InitKind getKind() const { return Kind; }
|
|
|
|
|
2011-07-29 19:07:07 +00:00
|
|
|
protected:
|
2012-10-10 20:24:40 +00:00
|
|
|
explicit Init(InitKind K) : Kind(K) {}
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-13 22:25:51 +00:00
|
|
|
public:
|
2002-12-02 01:23:04 +00:00
|
|
|
virtual ~Init() {}
|
|
|
|
|
2002-12-02 16:57:01 +00:00
|
|
|
/// isComplete - This virtual method should be overridden by values that may
|
|
|
|
/// not be completely specified yet.
|
|
|
|
virtual bool isComplete() const { return true; }
|
|
|
|
|
|
|
|
/// print - Print out this value.
|
2009-07-03 00:10:29 +00:00
|
|
|
void print(raw_ostream &OS) const { OS << getAsString(); }
|
2007-11-22 21:05:25 +00:00
|
|
|
|
|
|
|
/// getAsString - Convert this value to a string form.
|
|
|
|
virtual std::string getAsString() const = 0;
|
2011-08-10 18:27:45 +00:00
|
|
|
/// getAsUnquotedString - Convert this value to a string form,
|
|
|
|
/// without adding quote markers. This primaruly affects
|
|
|
|
/// StringInits where we will not surround the string value with
|
|
|
|
/// quotes.
|
2012-04-18 17:46:37 +00:00
|
|
|
virtual std::string getAsUnquotedString() const { return getAsString(); }
|
2002-12-02 16:57:01 +00:00
|
|
|
|
|
|
|
/// dump - Debugging method that may be called through a debugger, just
|
2009-07-03 00:10:29 +00:00
|
|
|
/// invokes print on stderr.
|
2002-12-02 01:23:04 +00:00
|
|
|
void dump() const;
|
|
|
|
|
2002-12-02 16:57:01 +00:00
|
|
|
/// convertInitializerTo - This virtual function is a simple call-back
|
|
|
|
/// function that should be overridden to call the appropriate
|
|
|
|
/// RecTy::convertValue method.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const = 0;
|
2002-12-02 16:57:01 +00:00
|
|
|
|
|
|
|
/// convertInitializerBitRange - This method is used to implement the bitrange
|
|
|
|
/// selection operator. Given an initializer, it selects the specified bits
|
2002-12-02 17:43:58 +00:00
|
|
|
/// out, returning them as a new init of bits type. If it is not legal to use
|
|
|
|
/// the bit subscript operator on this initializer, return null.
|
2002-12-02 16:57:01 +00:00
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *
|
2011-07-29 19:07:05 +00:00
|
|
|
convertInitializerBitRange(const std::vector<unsigned> &Bits) const {
|
2002-12-02 01:23:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Add initial support for list slices. This currently allows you to do stuff
like this:
def B {
list<int> X = [10, 20, 30, 4, 1, 1231, 20] [2-4,2,2,0-6];
}
... which isn't particularly useful, but more is to come.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15247 91177308-0d34-0410-b5e6-96231b3b80d8
2004-07-26 23:21:34 +00:00
|
|
|
/// convertInitListSlice - This method is used to implement the list slice
|
|
|
|
/// selection operator. Given an initializer, it selects the specified list
|
|
|
|
/// elements, returning them as a new init of list type. If it is not legal
|
|
|
|
/// to take a slice of this, return null.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *
|
2011-07-29 19:07:05 +00:00
|
|
|
convertInitListSlice(const std::vector<unsigned> &Elements) const {
|
Add initial support for list slices. This currently allows you to do stuff
like this:
def B {
list<int> X = [10, 20, 30, 4, 1, 1231, 20] [2-4,2,2,0-6];
}
... which isn't particularly useful, but more is to come.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15247 91177308-0d34-0410-b5e6-96231b3b80d8
2004-07-26 23:21:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-02 16:42:52 +00:00
|
|
|
/// getFieldType - This method is used to implement the FieldInit class.
|
|
|
|
/// Implementors of this method should return the type of the named field if
|
|
|
|
/// they are of record type.
|
|
|
|
///
|
|
|
|
virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
|
|
|
|
|
2002-12-03 06:00:33 +00:00
|
|
|
/// getFieldInit - This method complements getFieldType to return the
|
|
|
|
/// initializer for the specified field. If getFieldType returns non-null
|
|
|
|
/// this method should return non-null, otherwise it returns null.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *getFieldInit(Record &R, const RecordVal *RV,
|
|
|
|
const std::string &FieldName) const {
|
2002-12-03 06:00:33 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2002-12-02 16:57:01 +00:00
|
|
|
/// resolveReferences - This method is used by classes that refer to other
|
2009-11-21 22:44:20 +00:00
|
|
|
/// variables which may not be defined at the time the expression is formed.
|
2002-12-02 16:57:01 +00:00
|
|
|
/// If a value is set for the variable later, this method will be called on
|
|
|
|
/// users of the value to allow the value to propagate out.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const {
|
|
|
|
return const_cast<Init *>(this);
|
2005-04-19 03:36:21 +00:00
|
|
|
}
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
/// getBit - This method is used to return the initializer for the specified
|
|
|
|
/// bit.
|
|
|
|
virtual Init *getBit(unsigned Bit) const = 0;
|
|
|
|
|
|
|
|
/// getBitVar - This method is used to retrieve the initializer for bit
|
|
|
|
/// reference. For non-VarBitInit, it simply returns itself.
|
|
|
|
virtual Init *getBitVar() const { return const_cast<Init*>(this); }
|
|
|
|
|
|
|
|
/// getBitNum - This method is used to retrieve the bit number of a bit
|
|
|
|
/// reference. For non-VarBitInit, it simply returns 0.
|
|
|
|
virtual unsigned getBitNum() const { return 0; }
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2009-07-03 00:10:29 +00:00
|
|
|
inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
|
2002-12-02 01:23:04 +00:00
|
|
|
I.print(OS); return OS;
|
|
|
|
}
|
|
|
|
|
2009-05-14 22:23:47 +00:00
|
|
|
/// TypedInit - This is the common super-class of types that have a specific,
|
|
|
|
/// explicit, type.
|
|
|
|
///
|
|
|
|
class TypedInit : public Init {
|
|
|
|
RecTy *Ty;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
TypedInit(const TypedInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
TypedInit &operator=(const TypedInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
protected:
|
2012-10-10 20:24:40 +00:00
|
|
|
explicit TypedInit(InitKind K, RecTy *T) : Init(K), Ty(T) {}
|
2011-07-11 23:06:52 +00:00
|
|
|
|
2011-07-29 19:07:07 +00:00
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() >= IK_FirstTypedInit &&
|
|
|
|
I->getKind() <= IK_LastTypedInit;
|
|
|
|
}
|
2009-05-14 22:23:47 +00:00
|
|
|
RecTy *getType() const { return Ty; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *
|
2011-07-29 19:07:05 +00:00
|
|
|
convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *
|
2011-07-29 19:07:05 +00:00
|
|
|
convertInitListSlice(const std::vector<unsigned> &Elements) const;
|
2009-05-14 22:23:47 +00:00
|
|
|
|
2010-09-03 21:00:49 +00:00
|
|
|
/// getFieldType - This method is used to implement the FieldInit class.
|
|
|
|
/// Implementors of this method should return the type of the named field if
|
|
|
|
/// they are of record type.
|
|
|
|
///
|
|
|
|
virtual RecTy *getFieldType(const std::string &FieldName) const;
|
|
|
|
|
2009-05-14 22:23:47 +00:00
|
|
|
/// resolveListElementReference - This method is used to implement
|
|
|
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
|
|
|
/// now, we return the resolved value, otherwise we return null.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const = 0;
|
2009-05-14 22:23:47 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// UnsetInit - ? - Represents an uninitialized value
|
|
|
|
///
|
2004-10-27 16:14:51 +00:00
|
|
|
class UnsetInit : public Init {
|
2012-10-10 20:24:40 +00:00
|
|
|
UnsetInit() : Init(IK_UnsetInit) {}
|
2012-09-16 21:43:09 +00:00
|
|
|
UnsetInit(const UnsetInit &) LLVM_DELETED_FUNCTION;
|
|
|
|
UnsetInit &operator=(const UnsetInit &Other) LLVM_DELETED_FUNCTION;
|
2011-12-20 02:50:00 +00:00
|
|
|
virtual void anchor();
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2004-10-27 16:14:51 +00:00
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_UnsetInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static UnsetInit *get();
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<UnsetInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
|
|
|
return const_cast<UnsetInit*>(this);
|
|
|
|
}
|
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
virtual bool isComplete() const { return false; }
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const { return "?"; }
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// BitInit - true/false - Represent a concrete initializer for a bit.
|
|
|
|
///
|
2002-12-02 01:23:04 +00:00
|
|
|
class BitInit : public Init {
|
|
|
|
bool Value;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-10-10 20:24:40 +00:00
|
|
|
explicit BitInit(bool V) : Init(IK_BitInit), Value(V) {}
|
2012-09-16 21:43:09 +00:00
|
|
|
BitInit(const BitInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
BitInit &operator=(BitInit &Other) LLVM_DELETED_FUNCTION;
|
2011-12-20 02:50:00 +00:00
|
|
|
virtual void anchor();
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_BitInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static BitInit *get(bool V);
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
bool getValue() const { return Value; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<BitInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
|
|
|
assert(Bit < 1 && "Bit index out of range!");
|
|
|
|
return const_cast<BitInit*>(this);
|
|
|
|
}
|
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const { return Value ? "1" : "0"; }
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
|
|
|
|
/// It contains a vector of bits, whose size is determined by the type.
|
|
|
|
///
|
2011-07-29 19:07:11 +00:00
|
|
|
class BitsInit : public Init, public FoldingSetNode {
|
2011-07-29 22:43:06 +00:00
|
|
|
std::vector<Init*> Bits;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-10-10 20:24:40 +00:00
|
|
|
BitsInit(ArrayRef<Init *> Range)
|
|
|
|
: Init(IK_BitsInit), Bits(Range.begin(), Range.end()) {}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
BitsInit(const BitsInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
BitsInit &operator=(const BitsInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_BitsInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static BitsInit *get(ArrayRef<Init *> Range);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 19:07:11 +00:00
|
|
|
void Profile(FoldingSetNodeID &ID) const;
|
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
unsigned getNumBits() const { return Bits.size(); }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<BitsInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *
|
2011-07-29 19:07:05 +00:00
|
|
|
convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
virtual bool isComplete() const {
|
|
|
|
for (unsigned i = 0; i != getNumBits(); ++i)
|
|
|
|
if (!getBit(i)->isComplete()) return false;
|
|
|
|
return true;
|
|
|
|
}
|
2010-04-09 21:01:02 +00:00
|
|
|
bool allInComplete() const {
|
|
|
|
for (unsigned i = 0; i != getNumBits(); ++i)
|
|
|
|
if (getBit(i)->isComplete()) return false;
|
|
|
|
return true;
|
|
|
|
}
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
|
|
|
assert(Bit < Bits.size() && "Bit index out of range!");
|
|
|
|
return Bits[Bit];
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// IntInit - 7 - Represent an initalization by a literal integer value.
|
|
|
|
///
|
2009-06-08 20:23:18 +00:00
|
|
|
class IntInit : public TypedInit {
|
2008-10-17 01:33:43 +00:00
|
|
|
int64_t Value;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-10-10 20:24:40 +00:00
|
|
|
explicit IntInit(int64_t V)
|
|
|
|
: TypedInit(IK_IntInit, IntRecTy::get()), Value(V) {}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
IntInit(const IntInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
IntInit &operator=(const IntInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_IntInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static IntInit *get(int64_t V);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2008-10-17 01:33:43 +00:00
|
|
|
int64_t getValue() const { return Value; }
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<IntInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *
|
2011-07-29 19:07:05 +00:00
|
|
|
convertInitializerBitRange(const std::vector<unsigned> &Bits) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2009-06-08 20:23:18 +00:00
|
|
|
|
|
|
|
/// resolveListElementReference - This method is used to implement
|
|
|
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
|
|
|
/// now, we return the resolved value, otherwise we return null.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const {
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Illegal element reference off int");
|
2009-06-08 20:23:18 +00:00
|
|
|
}
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
2012-09-09 20:34:25 +00:00
|
|
|
return BitInit::get((Value & (1ULL << Bit)) != 0);
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// StringInit - "foo" - Represent an initialization by a string value.
|
|
|
|
///
|
2009-05-14 22:23:47 +00:00
|
|
|
class StringInit : public TypedInit {
|
2002-12-02 01:23:04 +00:00
|
|
|
std::string Value;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-11 23:06:52 +00:00
|
|
|
explicit StringInit(const std::string &V)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_StringInit, StringRecTy::get()), Value(V) {}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
StringInit(const StringInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
StringInit &operator=(const StringInit &Other) LLVM_DELETED_FUNCTION;
|
2011-12-20 02:50:00 +00:00
|
|
|
virtual void anchor();
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_StringInit;
|
|
|
|
}
|
2012-01-13 03:16:35 +00:00
|
|
|
static StringInit *get(StringRef);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2003-08-01 04:37:57 +00:00
|
|
|
const std::string &getValue() const { return Value; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<StringInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const { return "\"" + Value + "\""; }
|
2011-08-10 18:27:45 +00:00
|
|
|
virtual std::string getAsUnquotedString() const { return Value; }
|
2009-05-14 22:23:47 +00:00
|
|
|
|
|
|
|
/// resolveListElementReference - This method is used to implement
|
|
|
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
|
|
|
/// now, we return the resolved value, otherwise we return null.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const {
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Illegal element reference off string");
|
2009-05-14 22:23:47 +00:00
|
|
|
}
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
|
|
|
llvm_unreachable("Illegal bit reference off string");
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
/// ListInit - [AL, AH, CL] - Represent a list of defs
|
|
|
|
///
|
2011-07-29 19:07:16 +00:00
|
|
|
class ListInit : public TypedInit, public FoldingSetNode {
|
2011-07-29 22:43:06 +00:00
|
|
|
std::vector<Init*> Values;
|
2002-12-02 01:23:04 +00:00
|
|
|
public:
|
2011-07-29 22:43:06 +00:00
|
|
|
typedef std::vector<Init*>::const_iterator const_iterator;
|
2009-05-14 22:38:31 +00:00
|
|
|
|
2011-07-29 19:07:16 +00:00
|
|
|
private:
|
2011-07-29 22:43:06 +00:00
|
|
|
explicit ListInit(ArrayRef<Init *> Range, RecTy *EltTy)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_ListInit, ListRecTy::get(EltTy)),
|
|
|
|
Values(Range.begin(), Range.end()) {}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
ListInit(const ListInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
ListInit &operator=(const ListInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_ListInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static ListInit *get(ArrayRef<Init *> Range, RecTy *EltTy);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 19:07:16 +00:00
|
|
|
void Profile(FoldingSetNodeID &ID) const;
|
|
|
|
|
2003-08-03 18:17:22 +00:00
|
|
|
unsigned getSize() const { return Values.size(); }
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getElement(unsigned i) const {
|
2003-08-03 18:17:22 +00:00
|
|
|
assert(i < Values.size() && "List element index out of range!");
|
|
|
|
return Values[i];
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2007-02-27 22:08:27 +00:00
|
|
|
Record *getElementAsRecord(unsigned i) const;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual Init *
|
|
|
|
convertInitListSlice(const std::vector<unsigned> &Elements) const;
|
Add initial support for list slices. This currently allows you to do stuff
like this:
def B {
list<int> X = [10, 20, 30, 4, 1, 1231, 20] [2-4,2,2,0-6];
}
... which isn't particularly useful, but more is to come.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15247 91177308-0d34-0410-b5e6-96231b3b80d8
2004-07-26 23:21:34 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<ListInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2004-07-27 01:01:21 +00:00
|
|
|
/// resolveReferences - This method is used by classes that refer to other
|
|
|
|
/// variables which may not be defined at the time they expression is formed.
|
|
|
|
/// If a value is set for the variable later, this method will be called on
|
|
|
|
/// users of the value to allow the value to propagate out.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2004-07-27 01:01:21 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2008-01-21 22:30:26 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
ArrayRef<Init*> getValues() const { return Values; }
|
2011-07-29 19:06:59 +00:00
|
|
|
|
2008-01-21 22:30:26 +00:00
|
|
|
inline const_iterator begin() const { return Values.begin(); }
|
|
|
|
inline const_iterator end () const { return Values.end(); }
|
|
|
|
|
|
|
|
inline size_t size () const { return Values.size(); }
|
|
|
|
inline bool empty() const { return Values.empty(); }
|
2009-06-08 20:23:18 +00:00
|
|
|
|
|
|
|
/// resolveListElementReference - This method is used to implement
|
|
|
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
|
|
|
/// now, we return the resolved value, otherwise we return null.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const;
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
|
|
|
llvm_unreachable("Illegal bit reference off list");
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 17:43:58 +00:00
|
|
|
|
2009-05-14 20:54:48 +00:00
|
|
|
/// OpInit - Base class for operators
|
|
|
|
///
|
|
|
|
class OpInit : public TypedInit {
|
2012-09-16 21:43:09 +00:00
|
|
|
OpInit(const OpInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
OpInit &operator=(OpInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-11 23:06:52 +00:00
|
|
|
|
2011-07-29 19:07:07 +00:00
|
|
|
protected:
|
2012-10-10 20:24:40 +00:00
|
|
|
explicit OpInit(InitKind K, RecTy *Type) : TypedInit(K, Type) {}
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() >= IK_FirstOpInit &&
|
|
|
|
I->getKind() <= IK_LastOpInit;
|
|
|
|
}
|
2009-05-14 20:54:48 +00:00
|
|
|
// Clone - Clone this operator, replacing arguments with the new list
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual OpInit *clone(std::vector<Init *> &Operands) const = 0;
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2009-08-12 22:10:57 +00:00
|
|
|
virtual int getNumOperands() const = 0;
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *getOperand(int i) const = 0;
|
2009-05-14 20:54:48 +00:00
|
|
|
|
|
|
|
// Fold - If possible, fold this to a simpler init. Return this if not
|
|
|
|
// possible to fold.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0;
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<OpInit *>(this));
|
2009-05-14 20:54:48 +00:00
|
|
|
}
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const;
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned Bit) const;
|
2009-05-14 20:54:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// UnOpInit - !op (X) - Transform an init.
|
|
|
|
///
|
2009-05-14 21:22:49 +00:00
|
|
|
class UnOpInit : public OpInit {
|
|
|
|
public:
|
2011-01-07 17:05:37 +00:00
|
|
|
enum UnaryOp { CAST, HEAD, TAIL, EMPTY };
|
2009-05-14 21:22:49 +00:00
|
|
|
private:
|
|
|
|
UnaryOp Opc;
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *LHS;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type)
|
2012-10-10 20:24:40 +00:00
|
|
|
: OpInit(IK_UnOpInit, Type), Opc(opc), LHS(lhs) {}
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
UnOpInit(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
UnOpInit &operator=(const UnOpInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2009-05-14 21:22:49 +00:00
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_UnOpInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type);
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2009-05-14 21:22:49 +00:00
|
|
|
// Clone - Clone this operator, replacing arguments with the new list
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual OpInit *clone(std::vector<Init *> &Operands) const {
|
2009-05-15 03:03:14 +00:00
|
|
|
assert(Operands.size() == 1 &&
|
|
|
|
"Wrong number of operands for unary operation");
|
2011-07-29 19:07:07 +00:00
|
|
|
return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
|
2009-05-14 21:22:49 +00:00
|
|
|
}
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual int getNumOperands() const { return 1; }
|
|
|
|
virtual Init *getOperand(int i) const {
|
2009-05-14 21:22:49 +00:00
|
|
|
assert(i == 0 && "Invalid operand id for unary operator");
|
|
|
|
return getOperand();
|
|
|
|
}
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2009-05-14 21:22:49 +00:00
|
|
|
UnaryOp getOpcode() const { return Opc; }
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getOperand() const { return LHS; }
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2009-05-14 21:22:49 +00:00
|
|
|
// Fold - If possible, fold this to a simpler init. Return this if not
|
|
|
|
// possible to fold.
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2009-05-14 21:22:49 +00:00
|
|
|
virtual std::string getAsString() const;
|
|
|
|
};
|
2009-04-23 21:25:15 +00:00
|
|
|
|
|
|
|
/// BinOpInit - !op (X, Y) - Combine two inits.
|
|
|
|
///
|
2009-05-14 20:54:48 +00:00
|
|
|
class BinOpInit : public OpInit {
|
2009-04-23 21:25:15 +00:00
|
|
|
public:
|
2013-01-25 14:49:08 +00:00
|
|
|
enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
|
2009-04-23 21:25:15 +00:00
|
|
|
private:
|
|
|
|
BinaryOp Opc;
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *LHS, *RHS;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
|
2012-10-10 20:24:40 +00:00
|
|
|
OpInit(IK_BinOpInit, Type), Opc(opc), LHS(lhs), RHS(rhs) {}
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
BinOpInit(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
BinOpInit &operator=(const BinOpInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_BinOpInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
|
|
|
|
RecTy *Type);
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2009-05-14 20:54:48 +00:00
|
|
|
// Clone - Clone this operator, replacing arguments with the new list
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual OpInit *clone(std::vector<Init *> &Operands) const {
|
2009-05-15 03:03:14 +00:00
|
|
|
assert(Operands.size() == 2 &&
|
|
|
|
"Wrong number of operands for binary operation");
|
2011-07-29 19:07:07 +00:00
|
|
|
return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
|
2009-05-14 20:54:48 +00:00
|
|
|
}
|
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual int getNumOperands() const { return 2; }
|
|
|
|
virtual Init *getOperand(int i) const {
|
2009-05-15 03:03:14 +00:00
|
|
|
assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
|
2009-05-14 20:54:48 +00:00
|
|
|
if (i == 0) {
|
|
|
|
return getLHS();
|
2009-11-22 04:24:42 +00:00
|
|
|
} else {
|
2009-05-14 20:54:48 +00:00
|
|
|
return getRHS();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-23 21:25:15 +00:00
|
|
|
BinaryOp getOpcode() const { return Opc; }
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getLHS() const { return LHS; }
|
|
|
|
Init *getRHS() const { return RHS; }
|
2009-04-23 21:25:15 +00:00
|
|
|
|
|
|
|
// Fold - If possible, fold this to a simpler init. Return this if not
|
|
|
|
// possible to fold.
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
|
2009-04-23 21:25:15 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2009-04-23 21:25:15 +00:00
|
|
|
virtual std::string getAsString() const;
|
|
|
|
};
|
|
|
|
|
2009-05-14 20:54:48 +00:00
|
|
|
/// TernOpInit - !op (X, Y, Z) - Combine two inits.
|
|
|
|
///
|
2009-05-14 21:54:42 +00:00
|
|
|
class TernOpInit : public OpInit {
|
|
|
|
public:
|
2009-06-09 18:31:17 +00:00
|
|
|
enum TernaryOp { SUBST, FOREACH, IF };
|
2009-05-14 21:54:42 +00:00
|
|
|
private:
|
|
|
|
TernaryOp Opc;
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *LHS, *MHS, *RHS;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
|
2011-07-29 19:07:05 +00:00
|
|
|
RecTy *Type) :
|
2012-10-10 20:24:40 +00:00
|
|
|
OpInit(IK_TernOpInit, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
TernOpInit(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
TernOpInit &operator=(const TernOpInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_TernOpInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static TernOpInit *get(TernaryOp opc, Init *lhs,
|
|
|
|
Init *mhs, Init *rhs,
|
|
|
|
RecTy *Type);
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2009-05-14 21:54:42 +00:00
|
|
|
// Clone - Clone this operator, replacing arguments with the new list
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual OpInit *clone(std::vector<Init *> &Operands) const {
|
2009-05-15 03:03:14 +00:00
|
|
|
assert(Operands.size() == 3 &&
|
|
|
|
"Wrong number of operands for ternary operation");
|
2011-07-29 19:07:07 +00:00
|
|
|
return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
|
|
|
|
getType());
|
2009-05-14 21:54:42 +00:00
|
|
|
}
|
|
|
|
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual int getNumOperands() const { return 3; }
|
|
|
|
virtual Init *getOperand(int i) const {
|
2009-05-15 03:03:14 +00:00
|
|
|
assert((i == 0 || i == 1 || i == 2) &&
|
|
|
|
"Invalid operand id for ternary operator");
|
2009-05-14 21:54:42 +00:00
|
|
|
if (i == 0) {
|
|
|
|
return getLHS();
|
2009-11-22 04:24:42 +00:00
|
|
|
} else if (i == 1) {
|
2009-05-14 21:54:42 +00:00
|
|
|
return getMHS();
|
2009-11-22 04:24:42 +00:00
|
|
|
} else {
|
2009-05-14 21:54:42 +00:00
|
|
|
return getRHS();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TernaryOp getOpcode() const { return Opc; }
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getLHS() const { return LHS; }
|
|
|
|
Init *getMHS() const { return MHS; }
|
|
|
|
Init *getRHS() const { return RHS; }
|
2009-05-14 21:54:42 +00:00
|
|
|
|
|
|
|
// Fold - If possible, fold this to a simpler init. Return this if not
|
|
|
|
// possible to fold.
|
2012-09-16 07:39:55 +00:00
|
|
|
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2010-12-13 01:46:19 +00:00
|
|
|
virtual bool isComplete() const { return false; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2009-05-14 21:54:42 +00:00
|
|
|
virtual std::string getAsString() const;
|
|
|
|
};
|
2009-05-14 20:54:48 +00:00
|
|
|
|
2009-04-23 21:25:15 +00:00
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
|
|
|
|
///
|
2002-12-02 17:43:58 +00:00
|
|
|
class VarInit : public TypedInit {
|
2011-10-19 13:02:33 +00:00
|
|
|
Init *VarName;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-11 23:06:52 +00:00
|
|
|
explicit VarInit(const std::string &VN, RecTy *T)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_VarInit, T), VarName(StringInit::get(VN)) {}
|
2011-10-19 13:02:33 +00:00
|
|
|
explicit VarInit(Init *VN, RecTy *T)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_VarInit, T), VarName(VN) {}
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
VarInit(const VarInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
VarInit &operator=(const VarInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_VarInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static VarInit *get(const std::string &VN, RecTy *T);
|
|
|
|
static VarInit *get(Init *VN, RecTy *T);
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<VarInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2011-10-19 13:02:33 +00:00
|
|
|
const std::string &getName() const;
|
|
|
|
Init *getNameInit() const { return VarName; }
|
|
|
|
std::string getNameInitAsString() const {
|
|
|
|
return getNameInit()->getAsUnquotedString();
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const;
|
2002-12-02 17:43:58 +00:00
|
|
|
|
2002-12-02 16:42:52 +00:00
|
|
|
virtual RecTy *getFieldType(const std::string &FieldName) const;
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *getFieldInit(Record &R, const RecordVal *RV,
|
|
|
|
const std::string &FieldName) const;
|
2003-07-30 04:05:07 +00:00
|
|
|
|
|
|
|
/// resolveReferences - This method is used by classes that refer to other
|
|
|
|
/// variables which may not be defined at the time they expression is formed.
|
|
|
|
/// If a value is set for the variable later, this method will be called on
|
|
|
|
/// users of the value to allow the value to propagate out.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2005-04-22 00:00:37 +00:00
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBit(unsigned Bit) const;
|
|
|
|
|
2011-10-19 13:02:33 +00:00
|
|
|
virtual std::string getAsString() const { return getName(); }
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 16:13:23 +00:00
|
|
|
|
2002-12-02 17:43:58 +00:00
|
|
|
/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
|
2002-12-02 16:13:23 +00:00
|
|
|
///
|
2002-12-02 01:23:04 +00:00
|
|
|
class VarBitInit : public Init {
|
2011-07-29 22:43:06 +00:00
|
|
|
TypedInit *TI;
|
2002-12-02 01:23:04 +00:00
|
|
|
unsigned Bit;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-10-10 20:24:40 +00:00
|
|
|
VarBitInit(TypedInit *T, unsigned B) : Init(IK_VarBitInit), TI(T), Bit(B) {
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
assert(T->getType() &&
|
2012-10-05 03:32:00 +00:00
|
|
|
(isa<IntRecTy>(T->getType()) ||
|
|
|
|
(isa<BitsRecTy>(T->getType()) &&
|
|
|
|
cast<BitsRecTy>(T->getType())->getNumBits() > B)) &&
|
2002-12-02 17:43:58 +00:00
|
|
|
"Illegal VarBitInit expression!");
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
VarBitInit(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
VarBitInit &operator=(const VarBitInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_VarBitInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static VarBitInit *get(TypedInit *T, unsigned B);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<VarBitInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBitVar() const { return TI; }
|
|
|
|
virtual unsigned getBitNum() const { return Bit; }
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned B) const {
|
|
|
|
assert(B < 1 && "Bit index out of range!");
|
|
|
|
return const_cast<VarBitInit*>(this);
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2005-04-22 00:00:37 +00:00
|
|
|
/// VarListElementInit - List[4] - Represent access to one element of a var or
|
2004-07-27 01:01:21 +00:00
|
|
|
/// field.
|
|
|
|
class VarListElementInit : public TypedInit {
|
2011-07-29 22:43:06 +00:00
|
|
|
TypedInit *TI;
|
2004-07-27 01:01:21 +00:00
|
|
|
unsigned Element;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
VarListElementInit(TypedInit *T, unsigned E)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_VarListElementInit,
|
|
|
|
cast<ListRecTy>(T->getType())->getElementType()),
|
|
|
|
TI(T), Element(E) {
|
2012-10-05 03:32:00 +00:00
|
|
|
assert(T->getType() && isa<ListRecTy>(T->getType()) &&
|
2004-07-27 01:01:21 +00:00
|
|
|
"Illegal VarBitInit expression!");
|
|
|
|
}
|
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
VarListElementInit(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
void operator=(const VarListElementInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_VarListElementInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static VarListElementInit *get(TypedInit *T, unsigned E);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<VarListElementInit *>(this));
|
2004-07-27 01:01:21 +00:00
|
|
|
}
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
TypedInit *getVariable() const { return TI; }
|
2004-07-27 01:01:21 +00:00
|
|
|
unsigned getElementNum() const { return Element; }
|
|
|
|
|
|
|
|
/// resolveListElementReference - This method is used to implement
|
|
|
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
|
|
|
/// now, we return the resolved value, otherwise we return null.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R,
|
|
|
|
const RecordVal *RV,
|
|
|
|
unsigned Elt) const;
|
2004-07-27 01:01:21 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
|
|
|
|
virtual Init *getBit(unsigned Bit) const;
|
2004-07-27 01:01:21 +00:00
|
|
|
};
|
2002-12-02 16:13:23 +00:00
|
|
|
|
|
|
|
/// DefInit - AL - Represent a reference to a 'def' in the description
|
|
|
|
///
|
2009-05-14 22:23:47 +00:00
|
|
|
class DefInit : public TypedInit {
|
2002-12-02 01:23:04 +00:00
|
|
|
Record *Def;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-10-10 20:24:40 +00:00
|
|
|
DefInit(Record *D, RecordRecTy *T) : TypedInit(IK_DefInit, T), Def(D) {}
|
2011-07-18 17:02:57 +00:00
|
|
|
friend class Record;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
DefInit(const DefInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
DefInit &operator=(const DefInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_DefInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static DefInit *get(Record*);
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<DefInit *>(this));
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Record *getDef() const { return Def; }
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
//virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
|
2002-12-03 06:00:33 +00:00
|
|
|
|
|
|
|
virtual RecTy *getFieldType(const std::string &FieldName) const;
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *getFieldInit(Record &R, const RecordVal *RV,
|
|
|
|
const std::string &FieldName) const;
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2009-05-14 22:23:47 +00:00
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Illegal bit reference off def");
|
2009-05-14 22:23:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// resolveListElementReference - This method is used to implement
|
|
|
|
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
|
|
|
/// now, we return the resolved value, otherwise we return null.
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const {
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Illegal element reference off def");
|
2009-05-14 22:23:47 +00:00
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2002-12-02 16:42:52 +00:00
|
|
|
/// FieldInit - X.Y - Represent a reference to a subfield of a variable
|
|
|
|
///
|
2002-12-02 17:43:58 +00:00
|
|
|
class FieldInit : public TypedInit {
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *Rec; // Record we are referring to
|
2002-12-02 16:42:52 +00:00
|
|
|
std::string FieldName; // Field we are accessing
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
FieldInit(Init *R, const std::string &FN)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
|
2002-12-02 17:43:58 +00:00
|
|
|
assert(getType() && "FieldInit with non-record type!");
|
2002-12-02 16:42:52 +00:00
|
|
|
}
|
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
FieldInit(const FieldInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
FieldInit &operator=(const FieldInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_FieldInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static FieldInit *get(Init *R, const std::string &FN);
|
|
|
|
static FieldInit *get(Init *R, const Init *FN);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<FieldInit *>(this));
|
2002-12-02 16:42:52 +00:00
|
|
|
}
|
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBit(unsigned Bit) const;
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R,
|
|
|
|
const RecordVal *RV,
|
|
|
|
unsigned Elt) const;
|
2002-12-02 17:43:58 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2003-08-01 05:58:58 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const {
|
|
|
|
return Rec->getAsString() + "." + FieldName;
|
2002-12-02 16:42:52 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2006-03-30 22:50:40 +00:00
|
|
|
/// DagInit - (v a, b) - Represent a DAG tree value. DAG inits are required
|
|
|
|
/// to have at least one value then a (possibly empty) list of arguments. Each
|
|
|
|
/// argument can have a name associated with it.
|
2003-08-04 20:44:17 +00:00
|
|
|
///
|
2011-07-29 19:07:26 +00:00
|
|
|
class DagInit : public TypedInit, public FoldingSetNode {
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *Val;
|
2009-03-19 05:21:56 +00:00
|
|
|
std::string ValName;
|
2011-07-29 22:43:06 +00:00
|
|
|
std::vector<Init*> Args;
|
2003-08-10 22:14:13 +00:00
|
|
|
std::vector<std::string> ArgNames;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
DagInit(Init *V, const std::string &VN,
|
|
|
|
ArrayRef<Init *> ArgRange,
|
2011-07-29 19:07:26 +00:00
|
|
|
ArrayRef<std::string> NameRange)
|
2012-10-10 20:24:40 +00:00
|
|
|
: TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
|
2011-07-29 19:07:26 +00:00
|
|
|
Args(ArgRange.begin(), ArgRange.end()),
|
|
|
|
ArgNames(NameRange.begin(), NameRange.end()) {}
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2012-09-16 21:43:09 +00:00
|
|
|
DagInit(const DagInit &Other) LLVM_DELETED_FUNCTION;
|
|
|
|
DagInit &operator=(const DagInit &Other) LLVM_DELETED_FUNCTION;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
|
|
|
public:
|
2012-10-10 20:24:40 +00:00
|
|
|
static bool classof(const Init *I) {
|
|
|
|
return I->getKind() == IK_DagInit;
|
|
|
|
}
|
2011-07-29 22:43:06 +00:00
|
|
|
static DagInit *get(Init *V, const std::string &VN,
|
|
|
|
ArrayRef<Init *> ArgRange,
|
|
|
|
ArrayRef<std::string> NameRange);
|
|
|
|
static DagInit *get(Init *V, const std::string &VN,
|
|
|
|
const std::vector<
|
|
|
|
std::pair<Init*, std::string> > &args);
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 19:07:26 +00:00
|
|
|
void Profile(FoldingSetNodeID &ID) const;
|
2011-07-29 19:07:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *convertInitializerTo(RecTy *Ty) const {
|
|
|
|
return Ty->convertValue(const_cast<DagInit *>(this));
|
2003-08-04 20:44:17 +00:00
|
|
|
}
|
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getOperator() const { return Val; }
|
2003-08-10 22:14:13 +00:00
|
|
|
|
2009-03-19 05:21:56 +00:00
|
|
|
const std::string &getName() const { return ValName; }
|
|
|
|
|
2003-08-10 22:14:13 +00:00
|
|
|
unsigned getNumArgs() const { return Args.size(); }
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getArg(unsigned Num) const {
|
2003-08-10 22:14:13 +00:00
|
|
|
assert(Num < Args.size() && "Arg number out of range!");
|
|
|
|
return Args[Num];
|
|
|
|
}
|
|
|
|
const std::string &getArgName(unsigned Num) const {
|
|
|
|
assert(Num < ArgNames.size() && "Arg number out of range!");
|
|
|
|
return ArgNames[Num];
|
|
|
|
}
|
2003-08-04 20:44:17 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveReferences(Record &R, const RecordVal *RV) const;
|
2003-08-10 22:38:36 +00:00
|
|
|
|
2007-11-22 21:05:25 +00:00
|
|
|
virtual std::string getAsString() const;
|
2008-01-22 11:00:07 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
typedef std::vector<Init*>::const_iterator const_arg_iterator;
|
2008-01-22 11:00:07 +00:00
|
|
|
typedef std::vector<std::string>::const_iterator const_name_iterator;
|
|
|
|
|
|
|
|
inline const_arg_iterator arg_begin() const { return Args.begin(); }
|
|
|
|
inline const_arg_iterator arg_end () const { return Args.end(); }
|
|
|
|
|
|
|
|
inline size_t arg_size () const { return Args.size(); }
|
|
|
|
inline bool arg_empty() const { return Args.empty(); }
|
|
|
|
|
|
|
|
inline const_name_iterator name_begin() const { return ArgNames.begin(); }
|
|
|
|
inline const_name_iterator name_end () const { return ArgNames.end(); }
|
|
|
|
|
|
|
|
inline size_t name_size () const { return ArgNames.size(); }
|
|
|
|
inline bool name_empty() const { return ArgNames.empty(); }
|
|
|
|
|
Re-work bit/bits value resolving in tblgen
- This patch is inspired by the failure of the following code snippet
which is used to convert enumerable values into encoding bits to
improve the readability of td files.
class S<int s> {
bits<2> V = !if(!eq(s, 8), {0, 0},
!if(!eq(s, 16), {0, 1},
!if(!eq(s, 32), {1, 0},
!if(!eq(s, 64), {1, 1}, {?, ?}))));
}
Later, PR8330 is found to report not exactly the same bug relevant
issue to bit/bits values.
- Instead of resolving bit/bits values separately through
resolveBitReference(), this patch adds getBit() for all Inits and
resolves bit value by resolving plus getting the specified bit. This
unifies the resolving of bit with other values and removes redundant
logic for resolving bit only. In addition,
BitsInit::resolveReferences() is optimized to take advantage of this
origanization by resolving VarBitInit's variable reference first and
then getting bits from it.
- The type interference in '!if' operator is revised to support possible
combinations of int and bits/bit in MHS and RHS.
- As there may be illegal assignments from integer value to bit, says
assign 2 to a bit, but we only check this during instantiation in some
cases, e.g.
bit V = !if(!eq(x, 17), 0, 2);
Verbose diagnostic message is generated when invalid value is
resolveed to help locating the error.
- PR8330 is fixed as well.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163360 91177308-0d34-0410-b5e6-96231b3b80d8
2012-09-06 23:32:48 +00:00
|
|
|
virtual Init *getBit(unsigned Bit) const {
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Illegal bit reference off dag");
|
2009-05-14 22:23:47 +00:00
|
|
|
}
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
|
|
|
unsigned Elt) const {
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Illegal element reference off dag");
|
2009-05-14 22:23:47 +00:00
|
|
|
}
|
2003-08-04 20:44:17 +00:00
|
|
|
};
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// High-Level Classes
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
class RecordVal {
|
2011-09-02 20:12:07 +00:00
|
|
|
Init *Name;
|
2002-12-02 01:23:04 +00:00
|
|
|
RecTy *Ty;
|
|
|
|
unsigned Prefix;
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *Value;
|
2002-12-02 01:23:04 +00:00
|
|
|
public:
|
2011-09-02 20:12:07 +00:00
|
|
|
RecordVal(Init *N, RecTy *T, unsigned P);
|
2002-12-02 01:23:04 +00:00
|
|
|
RecordVal(const std::string &N, RecTy *T, unsigned P);
|
|
|
|
|
2011-09-02 20:12:07 +00:00
|
|
|
const std::string &getName() const;
|
2011-10-19 13:02:22 +00:00
|
|
|
const Init *getNameInit() const { return Name; }
|
|
|
|
std::string getNameInitAsString() const {
|
|
|
|
return getNameInit()->getAsUnquotedString();
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
unsigned getPrefix() const { return Prefix; }
|
|
|
|
RecTy *getType() const { return Ty; }
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getValue() const { return Value; }
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-07-29 22:43:06 +00:00
|
|
|
bool setValue(Init *V) {
|
2002-12-02 01:23:04 +00:00
|
|
|
if (V) {
|
|
|
|
Value = V->convertInitializerTo(Ty);
|
|
|
|
return Value == 0;
|
|
|
|
}
|
|
|
|
Value = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void dump() const;
|
2009-07-03 00:10:29 +00:00
|
|
|
void print(raw_ostream &OS, bool PrintSem = true) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2009-07-03 00:10:29 +00:00
|
|
|
inline raw_ostream &operator<<(raw_ostream &OS, const RecordVal &RV) {
|
2002-12-02 01:23:04 +00:00
|
|
|
RV.print(OS << " ");
|
|
|
|
return OS;
|
|
|
|
}
|
|
|
|
|
2004-10-23 04:58:50 +00:00
|
|
|
class Record {
|
2009-08-23 09:47:37 +00:00
|
|
|
static unsigned LastID;
|
|
|
|
|
|
|
|
// Unique record ID.
|
|
|
|
unsigned ID;
|
2011-08-10 18:27:46 +00:00
|
|
|
Init *Name;
|
Print out the location of expanded multiclass defs in TableGen errors.
When reporting an error for a defm, we would previously only report the
location of the outer defm, which is not always where the error is.
Now we also print the location of the expanded multiclass defs:
lib/Target/X86/X86InstrSSE.td:2902:12: error: foo
defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
^
lib/Target/X86/X86InstrSSE.td:2801:11: note: instantiated from multiclass
defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
^
lib/Target/X86/X86InstrSSE.td:194:5: note: instantiated from multiclass
def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
^
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162409 91177308-0d34-0410-b5e6-96231b3b80d8
2012-08-22 23:33:58 +00:00
|
|
|
// Location where record was instantiated, followed by the location of
|
|
|
|
// multiclass prototypes used.
|
|
|
|
SmallVector<SMLoc, 4> Locs;
|
2011-10-19 13:02:42 +00:00
|
|
|
std::vector<Init *> TemplateArgs;
|
2002-12-02 01:23:04 +00:00
|
|
|
std::vector<RecordVal> Values;
|
2013-01-10 18:50:11 +00:00
|
|
|
std::vector<Record *> SuperClasses;
|
|
|
|
std::vector<SMRange> SuperClassRanges;
|
2010-12-13 00:23:57 +00:00
|
|
|
|
|
|
|
// Tracks Record instances. Not owned by Record.
|
|
|
|
RecordKeeper &TrackedRecords;
|
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
DefInit *TheInit;
|
2013-01-10 18:50:05 +00:00
|
|
|
bool IsAnonymous;
|
2011-07-18 17:02:57 +00:00
|
|
|
|
2011-10-19 13:02:45 +00:00
|
|
|
void init();
|
2011-08-10 18:27:46 +00:00
|
|
|
void checkName();
|
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
public:
|
|
|
|
|
2010-12-15 04:48:22 +00:00
|
|
|
// Constructs a record.
|
Print out the location of expanded multiclass defs in TableGen errors.
When reporting an error for a defm, we would previously only report the
location of the outer defm, which is not always where the error is.
Now we also print the location of the expanded multiclass defs:
lib/Target/X86/X86InstrSSE.td:2902:12: error: foo
defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
^
lib/Target/X86/X86InstrSSE.td:2801:11: note: instantiated from multiclass
defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
^
lib/Target/X86/X86InstrSSE.td:194:5: note: instantiated from multiclass
def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
^
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162409 91177308-0d34-0410-b5e6-96231b3b80d8
2012-08-22 23:33:58 +00:00
|
|
|
explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
|
2013-01-10 18:50:05 +00:00
|
|
|
RecordKeeper &records, bool Anonymous = false) :
|
Print out the location of expanded multiclass defs in TableGen errors.
When reporting an error for a defm, we would previously only report the
location of the outer defm, which is not always where the error is.
Now we also print the location of the expanded multiclass defs:
lib/Target/X86/X86InstrSSE.td:2902:12: error: foo
defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
^
lib/Target/X86/X86InstrSSE.td:2801:11: note: instantiated from multiclass
defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
^
lib/Target/X86/X86InstrSSE.td:194:5: note: instantiated from multiclass
def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
^
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162409 91177308-0d34-0410-b5e6-96231b3b80d8
2012-08-22 23:33:58 +00:00
|
|
|
ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()),
|
2013-01-10 18:50:05 +00:00
|
|
|
TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) {
|
2011-10-19 13:03:21 +00:00
|
|
|
init();
|
2011-10-19 13:03:10 +00:00
|
|
|
}
|
2013-01-10 18:50:05 +00:00
|
|
|
explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
|
|
|
|
bool Anonymous = false) :
|
Print out the location of expanded multiclass defs in TableGen errors.
When reporting an error for a defm, we would previously only report the
location of the outer defm, which is not always where the error is.
Now we also print the location of the expanded multiclass defs:
lib/Target/X86/X86InstrSSE.td:2902:12: error: foo
defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
^
lib/Target/X86/X86InstrSSE.td:2801:11: note: instantiated from multiclass
defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
^
lib/Target/X86/X86InstrSSE.td:194:5: note: instantiated from multiclass
def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
^
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162409 91177308-0d34-0410-b5e6-96231b3b80d8
2012-08-22 23:33:58 +00:00
|
|
|
ID(LastID++), Name(N), Locs(locs.begin(), locs.end()),
|
2013-01-10 18:50:05 +00:00
|
|
|
TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) {
|
2011-10-19 13:03:21 +00:00
|
|
|
init();
|
2011-10-19 13:03:15 +00:00
|
|
|
}
|
2012-09-19 21:34:18 +00:00
|
|
|
|
|
|
|
// When copy-constructing a Record, we must still guarantee a globally unique
|
|
|
|
// ID number. All other fields can be copied normally.
|
|
|
|
Record(const Record &O) :
|
|
|
|
ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
|
|
|
|
Values(O.Values), SuperClasses(O.SuperClasses),
|
2013-01-10 18:50:11 +00:00
|
|
|
SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords),
|
|
|
|
TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { }
|
2012-09-19 21:34:18 +00:00
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
~Record() {}
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2010-09-21 14:59:50 +00:00
|
|
|
|
2010-03-01 22:09:11 +00:00
|
|
|
static unsigned getNewUID() { return LastID++; }
|
2010-09-21 14:59:50 +00:00
|
|
|
|
|
|
|
|
2009-08-23 09:47:37 +00:00
|
|
|
unsigned getID() const { return ID; }
|
|
|
|
|
2011-08-10 18:27:46 +00:00
|
|
|
const std::string &getName() const;
|
2011-10-19 13:02:28 +00:00
|
|
|
Init *getNameInit() const {
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
const std::string getNameInitAsString() const {
|
|
|
|
return getNameInit()->getAsUnquotedString();
|
|
|
|
}
|
|
|
|
|
2011-08-10 18:27:46 +00:00
|
|
|
void setName(Init *Name); // Also updates RecordKeeper.
|
2005-08-19 17:58:11 +00:00
|
|
|
void setName(const std::string &Name); // Also updates RecordKeeper.
|
2009-11-22 04:24:42 +00:00
|
|
|
|
Print out the location of expanded multiclass defs in TableGen errors.
When reporting an error for a defm, we would previously only report the
location of the outer defm, which is not always where the error is.
Now we also print the location of the expanded multiclass defs:
lib/Target/X86/X86InstrSSE.td:2902:12: error: foo
defm ADD : basic_sse12_fp_binop_s<0x58, "add", fadd, SSE_ALU_ITINS_S>,
^
lib/Target/X86/X86InstrSSE.td:2801:11: note: instantiated from multiclass
defm PD : sse12_fp_packed<opc, !strconcat(OpcodeStr, "pd"), OpNode, VR128,
^
lib/Target/X86/X86InstrSSE.td:194:5: note: instantiated from multiclass
def rm : PI<opc, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
^
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162409 91177308-0d34-0410-b5e6-96231b3b80d8
2012-08-22 23:33:58 +00:00
|
|
|
ArrayRef<SMLoc> getLoc() const { return Locs; }
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2011-07-18 17:02:57 +00:00
|
|
|
/// get the corresponding DefInit.
|
|
|
|
DefInit *getDefInit();
|
|
|
|
|
2011-10-19 13:02:42 +00:00
|
|
|
const std::vector<Init *> &getTemplateArgs() const {
|
2002-12-02 01:23:04 +00:00
|
|
|
return TemplateArgs;
|
|
|
|
}
|
|
|
|
const std::vector<RecordVal> &getValues() const { return Values; }
|
|
|
|
const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
|
2013-01-10 18:50:11 +00:00
|
|
|
ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-10-19 13:02:42 +00:00
|
|
|
bool isTemplateArg(Init *Name) const {
|
2002-12-02 01:23:04 +00:00
|
|
|
for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
|
|
|
|
if (TemplateArgs[i] == Name) return true;
|
|
|
|
return false;
|
|
|
|
}
|
2011-10-19 13:02:42 +00:00
|
|
|
bool isTemplateArg(StringRef Name) const {
|
|
|
|
return isTemplateArg(StringInit::get(Name.str()));
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2012-01-13 03:16:35 +00:00
|
|
|
const RecordVal *getValue(const Init *Name) const {
|
2002-12-02 01:23:04 +00:00
|
|
|
for (unsigned i = 0, e = Values.size(); i != e; ++i)
|
2012-01-13 03:16:35 +00:00
|
|
|
if (Values[i].getNameInit() == Name) return &Values[i];
|
2002-12-02 01:23:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2012-01-13 03:16:35 +00:00
|
|
|
const RecordVal *getValue(StringRef Name) const {
|
|
|
|
return getValue(StringInit::get(Name));
|
|
|
|
}
|
|
|
|
RecordVal *getValue(const Init *Name) {
|
2002-12-02 01:23:04 +00:00
|
|
|
for (unsigned i = 0, e = Values.size(); i != e; ++i)
|
2012-01-13 03:16:35 +00:00
|
|
|
if (Values[i].getNameInit() == Name) return &Values[i];
|
2002-12-02 01:23:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2012-01-13 03:16:35 +00:00
|
|
|
RecordVal *getValue(StringRef Name) {
|
|
|
|
return getValue(StringInit::get(Name));
|
|
|
|
}
|
2011-10-19 13:02:29 +00:00
|
|
|
|
2011-10-19 13:02:42 +00:00
|
|
|
void addTemplateArg(Init *Name) {
|
2002-12-02 01:23:04 +00:00
|
|
|
assert(!isTemplateArg(Name) && "Template arg already defined!");
|
|
|
|
TemplateArgs.push_back(Name);
|
|
|
|
}
|
2011-10-19 13:02:42 +00:00
|
|
|
void addTemplateArg(StringRef Name) {
|
|
|
|
addTemplateArg(StringInit::get(Name.str()));
|
|
|
|
}
|
2002-12-02 01:23:04 +00:00
|
|
|
|
|
|
|
void addValue(const RecordVal &RV) {
|
2012-01-13 03:16:35 +00:00
|
|
|
assert(getValue(RV.getNameInit()) == 0 && "Value already added!");
|
2002-12-02 01:23:04 +00:00
|
|
|
Values.push_back(RV);
|
2011-10-19 13:04:13 +00:00
|
|
|
if (Values.size() > 1)
|
|
|
|
// Keep NAME at the end of the list. It makes record dumps a
|
|
|
|
// bit prettier and allows TableGen tests to be written more
|
|
|
|
// naturally. Tests can use CHECK-NEXT to look for Record
|
|
|
|
// fields they expect to see after a def. They can't do that if
|
|
|
|
// NAME is the first Record field.
|
|
|
|
std::swap(Values[Values.size() - 2], Values[Values.size() - 1]);
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2011-10-19 13:02:29 +00:00
|
|
|
void removeValue(Init *Name) {
|
2003-07-30 04:56:05 +00:00
|
|
|
for (unsigned i = 0, e = Values.size(); i != e; ++i)
|
2011-10-19 13:02:29 +00:00
|
|
|
if (Values[i].getNameInit() == Name) {
|
2003-07-30 04:56:05 +00:00
|
|
|
Values.erase(Values.begin()+i);
|
|
|
|
return;
|
|
|
|
}
|
2012-02-05 22:14:15 +00:00
|
|
|
llvm_unreachable("Cannot remove an entry that does not exist!");
|
2003-07-30 04:56:05 +00:00
|
|
|
}
|
|
|
|
|
2011-10-19 13:02:29 +00:00
|
|
|
void removeValue(StringRef Name) {
|
|
|
|
removeValue(StringInit::get(Name.str()));
|
|
|
|
}
|
|
|
|
|
2009-03-13 22:20:10 +00:00
|
|
|
bool isSubClassOf(const Record *R) const {
|
2002-12-02 01:23:04 +00:00
|
|
|
for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
|
|
|
|
if (SuperClasses[i] == R)
|
2005-04-22 04:13:13 +00:00
|
|
|
return true;
|
2002-12-02 01:23:04 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-09-18 18:31:37 +00:00
|
|
|
bool isSubClassOf(StringRef Name) const {
|
2003-08-07 19:41:59 +00:00
|
|
|
for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
|
2011-10-19 13:02:47 +00:00
|
|
|
if (SuperClasses[i]->getNameInitAsString() == Name)
|
2003-08-07 19:41:59 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-10 18:50:11 +00:00
|
|
|
void addSuperClass(Record *R, SMRange Range) {
|
2002-12-02 01:23:04 +00:00
|
|
|
assert(!isSubClassOf(R) && "Already subclassing record!");
|
|
|
|
SuperClasses.push_back(R);
|
2013-01-10 18:50:11 +00:00
|
|
|
SuperClassRanges.push_back(Range);
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2005-04-19 03:36:21 +00:00
|
|
|
/// resolveReferences - If there are any field references that refer to fields
|
|
|
|
/// that have been filled in, we can propagate the values now.
|
|
|
|
///
|
|
|
|
void resolveReferences() { resolveReferencesTo(0); }
|
|
|
|
|
|
|
|
/// resolveReferencesTo - If anything in this record refers to RV, replace the
|
|
|
|
/// reference to RV with the RHS of RV. If RV is null, we resolve all
|
|
|
|
/// possible references.
|
|
|
|
void resolveReferencesTo(const RecordVal *RV);
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2010-12-13 00:23:57 +00:00
|
|
|
RecordKeeper &getRecords() const {
|
2010-12-15 04:48:22 +00:00
|
|
|
return TrackedRecords;
|
2010-12-13 00:23:57 +00:00
|
|
|
}
|
|
|
|
|
2013-01-10 18:50:05 +00:00
|
|
|
bool isAnonymous() const {
|
|
|
|
return IsAnonymous;
|
|
|
|
}
|
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
void dump() const;
|
2003-08-01 04:37:57 +00:00
|
|
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// High-level methods useful to tablegen back-ends
|
|
|
|
//
|
|
|
|
|
2003-08-01 06:27:59 +00:00
|
|
|
/// getValueInit - Return the initializer for a value with the specified name,
|
|
|
|
/// or throw an exception if the field does not exist.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
Init *getValueInit(StringRef FieldName) const;
|
2003-08-01 06:27:59 +00:00
|
|
|
|
2013-03-15 22:51:13 +00:00
|
|
|
/// Return true if the named field is unset.
|
|
|
|
bool isValueUnset(StringRef FieldName) const {
|
|
|
|
return getValueInit(FieldName) == UnsetInit::get();
|
|
|
|
}
|
|
|
|
|
2003-08-01 04:37:57 +00:00
|
|
|
/// getValueAsString - This method looks up the specified field and returns
|
|
|
|
/// its value as a string, throwing an exception if the field does not exist
|
|
|
|
/// or if the value is not a string.
|
|
|
|
///
|
2009-09-18 18:31:37 +00:00
|
|
|
std::string getValueAsString(StringRef FieldName) const;
|
2003-08-01 04:37:57 +00:00
|
|
|
|
2003-08-01 04:46:24 +00:00
|
|
|
/// getValueAsBitsInit - This method looks up the specified field and returns
|
|
|
|
/// its value as a BitsInit, throwing an exception if the field does not exist
|
|
|
|
/// or if the value is not the right type.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
BitsInit *getValueAsBitsInit(StringRef FieldName) const;
|
2003-08-01 04:46:24 +00:00
|
|
|
|
2003-08-01 06:15:10 +00:00
|
|
|
/// getValueAsListInit - This method looks up the specified field and returns
|
|
|
|
/// its value as a ListInit, throwing an exception if the field does not exist
|
|
|
|
/// or if the value is not the right type.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
ListInit *getValueAsListInit(StringRef FieldName) const;
|
2003-08-01 06:15:10 +00:00
|
|
|
|
2005-10-28 22:49:02 +00:00
|
|
|
/// getValueAsListOfDefs - This method looks up the specified field and
|
2007-11-11 11:19:37 +00:00
|
|
|
/// returns its value as a vector of records, throwing an exception if the
|
2005-10-28 22:49:02 +00:00
|
|
|
/// field does not exist or if the value is not the right type.
|
2005-10-28 21:46:31 +00:00
|
|
|
///
|
2009-09-18 18:31:37 +00:00
|
|
|
std::vector<Record*> getValueAsListOfDefs(StringRef FieldName) const;
|
2005-10-28 21:46:31 +00:00
|
|
|
|
2010-09-21 14:59:50 +00:00
|
|
|
/// getValueAsListOfInts - This method looks up the specified field and
|
|
|
|
/// returns its value as a vector of integers, throwing an exception if the
|
|
|
|
/// field does not exist or if the value is not the right type.
|
2007-11-11 11:19:37 +00:00
|
|
|
///
|
2009-09-18 18:31:37 +00:00
|
|
|
std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const;
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2011-06-27 21:06:21 +00:00
|
|
|
/// getValueAsListOfStrings - This method looks up the specified field and
|
|
|
|
/// returns its value as a vector of strings, throwing an exception if the
|
|
|
|
/// field does not exist or if the value is not the right type.
|
|
|
|
///
|
|
|
|
std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const;
|
|
|
|
|
2003-08-02 01:27:37 +00:00
|
|
|
/// getValueAsDef - This method looks up the specified field and returns its
|
|
|
|
/// value as a Record, throwing an exception if the field does not exist or if
|
|
|
|
/// the value is not the right type.
|
|
|
|
///
|
2009-09-18 18:31:37 +00:00
|
|
|
Record *getValueAsDef(StringRef FieldName) const;
|
2003-08-02 01:27:37 +00:00
|
|
|
|
2003-08-03 21:58:13 +00:00
|
|
|
/// getValueAsBit - This method looks up the specified field and returns its
|
|
|
|
/// value as a bit, throwing an exception if the field does not exist or if
|
|
|
|
/// the value is not the right type.
|
|
|
|
///
|
2009-09-18 18:31:37 +00:00
|
|
|
bool getValueAsBit(StringRef FieldName) const;
|
2003-08-03 21:58:13 +00:00
|
|
|
|
2012-08-23 19:34:46 +00:00
|
|
|
/// getValueAsBitOrUnset - This method looks up the specified field and
|
|
|
|
/// returns its value as a bit. If the field is unset, sets Unset to true and
|
|
|
|
/// retunrs false.
|
|
|
|
///
|
|
|
|
bool getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const;
|
|
|
|
|
2003-08-01 06:15:10 +00:00
|
|
|
/// getValueAsInt - This method looks up the specified field and returns its
|
2008-10-17 01:33:43 +00:00
|
|
|
/// value as an int64_t, throwing an exception if the field does not exist or
|
|
|
|
/// if the value is not the right type.
|
2003-08-01 06:15:10 +00:00
|
|
|
///
|
2009-09-18 18:31:37 +00:00
|
|
|
int64_t getValueAsInt(StringRef FieldName) const;
|
2003-08-07 06:00:43 +00:00
|
|
|
|
|
|
|
/// getValueAsDag - This method looks up the specified field and returns its
|
|
|
|
/// value as an Dag, throwing an exception if the field does not exist or if
|
|
|
|
/// the value is not the right type.
|
|
|
|
///
|
2011-07-29 22:43:06 +00:00
|
|
|
DagInit *getValueAsDag(StringRef FieldName) const;
|
2002-12-02 01:23:04 +00:00
|
|
|
};
|
|
|
|
|
2009-07-03 00:10:29 +00:00
|
|
|
raw_ostream &operator<<(raw_ostream &OS, const Record &R);
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2009-04-22 20:18:10 +00:00
|
|
|
struct MultiClass {
|
|
|
|
Record Rec; // Placeholder for template args and Name.
|
|
|
|
typedef std::vector<Record*> RecordVector;
|
|
|
|
RecordVector DefPrototypes;
|
2009-04-24 16:55:41 +00:00
|
|
|
|
|
|
|
void dump() const;
|
|
|
|
|
2012-04-18 17:46:37 +00:00
|
|
|
MultiClass(const std::string &Name, SMLoc Loc, RecordKeeper &Records) :
|
2010-12-13 00:23:57 +00:00
|
|
|
Rec(Name, Loc, Records) {}
|
2009-04-22 20:18:10 +00:00
|
|
|
};
|
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
class RecordKeeper {
|
|
|
|
std::map<std::string, Record*> Classes, Defs;
|
2012-02-22 16:09:41 +00:00
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
public:
|
|
|
|
~RecordKeeper() {
|
|
|
|
for (std::map<std::string, Record*>::iterator I = Classes.begin(),
|
2005-04-22 04:13:13 +00:00
|
|
|
E = Classes.end(); I != E; ++I)
|
2002-12-02 01:23:04 +00:00
|
|
|
delete I->second;
|
|
|
|
for (std::map<std::string, Record*>::iterator I = Defs.begin(),
|
2005-04-22 04:13:13 +00:00
|
|
|
E = Defs.end(); I != E; ++I)
|
2002-12-02 01:23:04 +00:00
|
|
|
delete I->second;
|
|
|
|
}
|
2005-04-22 00:00:37 +00:00
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
const std::map<std::string, Record*> &getClasses() const { return Classes; }
|
|
|
|
const std::map<std::string, Record*> &getDefs() const { return Defs; }
|
|
|
|
|
|
|
|
Record *getClass(const std::string &Name) const {
|
|
|
|
std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
|
|
|
|
return I == Classes.end() ? 0 : I->second;
|
|
|
|
}
|
|
|
|
Record *getDef(const std::string &Name) const {
|
|
|
|
std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
|
|
|
|
return I == Defs.end() ? 0 : I->second;
|
|
|
|
}
|
|
|
|
void addClass(Record *R) {
|
2012-05-24 22:17:36 +00:00
|
|
|
bool Ins = Classes.insert(std::make_pair(R->getName(), R)).second;
|
|
|
|
(void)Ins;
|
|
|
|
assert(Ins && "Class already exists");
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
void addDef(Record *R) {
|
2012-05-24 22:17:36 +00:00
|
|
|
bool Ins = Defs.insert(std::make_pair(R->getName(), R)).second;
|
|
|
|
(void)Ins;
|
|
|
|
assert(Ins && "Record already exists");
|
2002-12-02 01:23:04 +00:00
|
|
|
}
|
|
|
|
|
2005-08-19 17:58:11 +00:00
|
|
|
/// removeClass - Remove, but do not delete, the specified record.
|
|
|
|
///
|
|
|
|
void removeClass(const std::string &Name) {
|
|
|
|
assert(Classes.count(Name) && "Class does not exist!");
|
|
|
|
Classes.erase(Name);
|
|
|
|
}
|
|
|
|
/// removeDef - Remove, but do not delete, the specified record.
|
|
|
|
///
|
|
|
|
void removeDef(const std::string &Name) {
|
|
|
|
assert(Defs.count(Name) && "Def does not exist!");
|
|
|
|
Defs.erase(Name);
|
|
|
|
}
|
2009-11-22 04:24:42 +00:00
|
|
|
|
2003-08-01 04:09:58 +00:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
// High-level helper methods, useful for tablegen backends...
|
|
|
|
|
|
|
|
/// getAllDerivedDefinitions - This method returns all concrete definitions
|
|
|
|
/// that derive from the specified class name. If a class with the specified
|
2003-08-01 04:37:57 +00:00
|
|
|
/// name does not exist, an exception is thrown.
|
|
|
|
std::vector<Record*>
|
|
|
|
getAllDerivedDefinitions(const std::string &ClassName) const;
|
2003-08-01 04:09:58 +00:00
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
void dump() const;
|
|
|
|
};
|
|
|
|
|
2008-08-26 06:43:25 +00:00
|
|
|
/// LessRecord - Sorting predicate to sort record pointers by name.
|
|
|
|
///
|
|
|
|
struct LessRecord {
|
|
|
|
bool operator()(const Record *Rec1, const Record *Rec2) const {
|
Add StringRef::compare_numeric and use it to sort TableGen register records.
This means that our Registers are now ordered R7, R8, R9, R10, R12, ...
Not R1, R10, R11, R12, R2, R3, ...
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104745 91177308-0d34-0410-b5e6-96231b3b80d8
2010-05-26 21:47:28 +00:00
|
|
|
return StringRef(Rec1->getName()).compare_numeric(Rec2->getName()) < 0;
|
2008-08-26 06:43:25 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-09-19 01:47:00 +00:00
|
|
|
/// LessRecordByID - Sorting predicate to sort record pointers by their
|
|
|
|
/// unique ID. If you just need a deterministic order, use this, since it
|
|
|
|
/// just compares two `unsigned`; the other sorting predicates require
|
|
|
|
/// string manipulation.
|
|
|
|
struct LessRecordByID {
|
|
|
|
bool operator()(const Record *LHS, const Record *RHS) const {
|
|
|
|
return LHS->getID() < RHS->getID();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-11-22 04:24:42 +00:00
|
|
|
/// LessRecordFieldName - Sorting predicate to sort record pointers by their
|
2008-09-11 17:05:32 +00:00
|
|
|
/// name field.
|
2008-08-26 06:43:25 +00:00
|
|
|
///
|
|
|
|
struct LessRecordFieldName {
|
|
|
|
bool operator()(const Record *Rec1, const Record *Rec2) const {
|
|
|
|
return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
Improve the compression of the tablegen DiffLists by introducing a new sort
algorithm when assigning EnumValues to the synthesized registers.
The current algorithm, LessRecord, uses the StringRef compare_numeric
function. This function compares strings, while handling embedded numbers.
For example, the R600 backend registers are sorted as follows:
T1
T1_W
T1_X
T1_XYZW
T1_Y
T1_Z
T2
T2_W
T2_X
T2_XYZW
T2_Y
T2_Z
In this example, the 'scaling factor' is dEnum/dN = 6 because T0, T1, T2
have an EnumValue offset of 6 from one another. However, in other parts
of the register bank, the scaling factors are different:
dEnum/dN = 5:
KC0_128_W
KC0_128_X
KC0_128_XYZW
KC0_128_Y
KC0_128_Z
KC0_129_W
KC0_129_X
KC0_129_XYZW
KC0_129_Y
KC0_129_Z
The diff lists do not work correctly because different kinds of registers have
different 'scaling factors'. This new algorithm, LessRecordRegister, tries to
enforce a scaling factor of 1. For example, the registers are now sorted as
follows:
T1
T2
T3
...
T0_W
T1_W
T2_W
...
T0_X
T1_X
T2_X
...
KC0_128_W
KC0_129_W
KC0_130_W
...
For the Mips and R600 I see a 19% and 6% reduction in size, respectively. I
did see a few small regressions, but the differences were on the order of a
few bytes (e.g., AArch64 was 16 bytes). I suspect there will be even
greater wins for targets with larger register files.
Patch reviewed by Jakob.
rdar://14006013
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185094 91177308-0d34-0410-b5e6-96231b3b80d8
2013-06-27 19:38:13 +00:00
|
|
|
struct LessRecordRegister {
|
|
|
|
static size_t min(size_t a, size_t b) { return a < b ? a : b; }
|
|
|
|
static bool ascii_isdigit(char x) { return x >= '0' && x <= '9'; }
|
|
|
|
|
|
|
|
struct RecordParts {
|
|
|
|
SmallVector<std::pair< bool, StringRef>, 4> Parts;
|
|
|
|
|
|
|
|
RecordParts(StringRef Rec) {
|
|
|
|
if (Rec.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
size_t Len = 0;
|
|
|
|
const char *Start = Rec.data();
|
|
|
|
const char *Curr = Start;
|
|
|
|
bool isDigitPart = ascii_isdigit(Curr[0]);
|
|
|
|
for (size_t I = 0, E = Rec.size(); I != E; ++I, ++Len) {
|
|
|
|
bool isDigit = ascii_isdigit(Curr[I]);
|
|
|
|
if (isDigit != isDigitPart) {
|
|
|
|
Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
|
|
|
|
Len = 0;
|
|
|
|
Start = &Curr[I];
|
|
|
|
isDigitPart = ascii_isdigit(Curr[I]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Push the last part.
|
|
|
|
Parts.push_back(std::make_pair(isDigitPart, StringRef(Start, Len)));
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t size() { return Parts.size(); }
|
|
|
|
|
|
|
|
std::pair<bool, StringRef> getPart(size_t i) {
|
|
|
|
assert (i < Parts.size() && "Invalid idx!");
|
|
|
|
return Parts[i];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
bool operator()(const Record *Rec1, const Record *Rec2) const {
|
|
|
|
RecordParts LHSParts(StringRef(Rec1->getName()));
|
|
|
|
RecordParts RHSParts(StringRef(Rec2->getName()));
|
|
|
|
|
|
|
|
size_t LHSNumParts = LHSParts.size();
|
|
|
|
size_t RHSNumParts = RHSParts.size();
|
|
|
|
assert (LHSNumParts && RHSNumParts && "Expected at least one part!");
|
|
|
|
|
|
|
|
if (LHSNumParts != RHSNumParts)
|
|
|
|
return LHSNumParts < RHSNumParts;
|
|
|
|
|
|
|
|
// We expect the registers to be of the form [_a-zA-z]+([0-9]*[_a-zA-Z]*)*.
|
|
|
|
for (size_t I = 0, E = LHSNumParts; I < E; I+=2) {
|
|
|
|
std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
|
|
|
|
std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
|
2013-06-27 20:19:13 +00:00
|
|
|
// Expect even part to always be alpha.
|
|
|
|
assert (LHSPart.first == false && RHSPart.first == false &&
|
|
|
|
"Expected both parts to be alpha.");
|
|
|
|
if (int Res = LHSPart.second.compare(RHSPart.second))
|
|
|
|
return Res < 0;
|
Improve the compression of the tablegen DiffLists by introducing a new sort
algorithm when assigning EnumValues to the synthesized registers.
The current algorithm, LessRecord, uses the StringRef compare_numeric
function. This function compares strings, while handling embedded numbers.
For example, the R600 backend registers are sorted as follows:
T1
T1_W
T1_X
T1_XYZW
T1_Y
T1_Z
T2
T2_W
T2_X
T2_XYZW
T2_Y
T2_Z
In this example, the 'scaling factor' is dEnum/dN = 6 because T0, T1, T2
have an EnumValue offset of 6 from one another. However, in other parts
of the register bank, the scaling factors are different:
dEnum/dN = 5:
KC0_128_W
KC0_128_X
KC0_128_XYZW
KC0_128_Y
KC0_128_Z
KC0_129_W
KC0_129_X
KC0_129_XYZW
KC0_129_Y
KC0_129_Z
The diff lists do not work correctly because different kinds of registers have
different 'scaling factors'. This new algorithm, LessRecordRegister, tries to
enforce a scaling factor of 1. For example, the registers are now sorted as
follows:
T1
T2
T3
...
T0_W
T1_W
T2_W
...
T0_X
T1_X
T2_X
...
KC0_128_W
KC0_129_W
KC0_130_W
...
For the Mips and R600 I see a 19% and 6% reduction in size, respectively. I
did see a few small regressions, but the differences were on the order of a
few bytes (e.g., AArch64 was 16 bytes). I suspect there will be even
greater wins for targets with larger register files.
Patch reviewed by Jakob.
rdar://14006013
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185094 91177308-0d34-0410-b5e6-96231b3b80d8
2013-06-27 19:38:13 +00:00
|
|
|
}
|
|
|
|
for (size_t I = 1, E = LHSNumParts; I < E; I+=2) {
|
|
|
|
std::pair<bool, StringRef> LHSPart = LHSParts.getPart(I);
|
|
|
|
std::pair<bool, StringRef> RHSPart = RHSParts.getPart(I);
|
2013-06-27 20:19:13 +00:00
|
|
|
// Expect odd part to always be numeric.
|
|
|
|
assert (LHSPart.first == true && RHSPart.first == true &&
|
|
|
|
"Expected both parts to be numeric.");
|
|
|
|
if (LHSPart.second.size() != RHSPart.second.size())
|
|
|
|
return LHSPart.second.size() < RHSPart.second.size();
|
|
|
|
|
|
|
|
unsigned LHSVal, RHSVal;
|
2013-07-01 23:42:53 +00:00
|
|
|
|
|
|
|
bool LHSFailed = LHSPart.second.getAsInteger(10, LHSVal); (void)LHSFailed;
|
|
|
|
assert(!LHSFailed && "Unable to convert LHS to integer.");
|
|
|
|
bool RHSFailed = RHSPart.second.getAsInteger(10, RHSVal); (void)RHSFailed;
|
|
|
|
assert(!RHSFailed && "Unable to convert RHS to integer.");
|
|
|
|
|
2013-06-27 20:19:13 +00:00
|
|
|
if (LHSVal != RHSVal)
|
|
|
|
return LHSVal < RHSVal;
|
Improve the compression of the tablegen DiffLists by introducing a new sort
algorithm when assigning EnumValues to the synthesized registers.
The current algorithm, LessRecord, uses the StringRef compare_numeric
function. This function compares strings, while handling embedded numbers.
For example, the R600 backend registers are sorted as follows:
T1
T1_W
T1_X
T1_XYZW
T1_Y
T1_Z
T2
T2_W
T2_X
T2_XYZW
T2_Y
T2_Z
In this example, the 'scaling factor' is dEnum/dN = 6 because T0, T1, T2
have an EnumValue offset of 6 from one another. However, in other parts
of the register bank, the scaling factors are different:
dEnum/dN = 5:
KC0_128_W
KC0_128_X
KC0_128_XYZW
KC0_128_Y
KC0_128_Z
KC0_129_W
KC0_129_X
KC0_129_XYZW
KC0_129_Y
KC0_129_Z
The diff lists do not work correctly because different kinds of registers have
different 'scaling factors'. This new algorithm, LessRecordRegister, tries to
enforce a scaling factor of 1. For example, the registers are now sorted as
follows:
T1
T2
T3
...
T0_W
T1_W
T2_W
...
T0_X
T1_X
T2_X
...
KC0_128_W
KC0_129_W
KC0_130_W
...
For the Mips and R600 I see a 19% and 6% reduction in size, respectively. I
did see a few small regressions, but the differences were on the order of a
few bytes (e.g., AArch64 was 16 bytes). I suspect there will be even
greater wins for targets with larger register files.
Patch reviewed by Jakob.
rdar://14006013
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185094 91177308-0d34-0410-b5e6-96231b3b80d8
2013-06-27 19:38:13 +00:00
|
|
|
}
|
|
|
|
return LHSNumParts < RHSNumParts;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-03 00:10:29 +00:00
|
|
|
raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
|
2002-12-02 01:23:04 +00:00
|
|
|
|
2011-10-19 13:02:36 +00:00
|
|
|
/// QualifyName - Return an Init with a qualifier prefix referring
|
|
|
|
/// to CurRec's name.
|
|
|
|
Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
|
|
|
|
Init *Name, const std::string &Scoper);
|
|
|
|
|
|
|
|
/// QualifyName - Return an Init with a qualifier prefix referring
|
|
|
|
/// to CurRec's name.
|
|
|
|
Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
|
|
|
|
const std::string &Name, const std::string &Scoper);
|
|
|
|
|
2003-11-11 22:41:34 +00:00
|
|
|
} // End llvm namespace
|
|
|
|
|
2002-12-02 01:23:04 +00:00
|
|
|
#endif
|