2007-11-18 16:46:26 +08:00
|
|
|
//===- LLLexer.cpp - Lexer for .ll Files ----------------------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2007-11-18 16:46:26 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Implement the Lexer for .ll files.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "LLLexer.h"
|
2016-08-19 01:56:27 +08:00
|
|
|
#include "llvm/ADT/APInt.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2013-01-19 07:05:41 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/Twine.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
|
|
#include "llvm/IR/Instruction.h"
|
2009-07-12 04:10:48 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2009-07-03 06:46:18 +08:00
|
|
|
#include "llvm/Support/SourceMgr.h"
|
2016-08-19 01:56:27 +08:00
|
|
|
#include <cassert>
|
2010-12-20 04:43:38 +08:00
|
|
|
#include <cctype>
|
2009-08-24 18:34:41 +08:00
|
|
|
#include <cstdio>
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2010-09-28 01:42:11 +08:00
|
|
|
bool LLLexer::Error(LocTy ErrorLoc, const Twine &Msg) const {
|
2011-10-16 13:43:57 +08:00
|
|
|
ErrorInfo = SM.GetMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
|
2009-01-02 15:01:27 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-04-06 06:42:53 +08:00
|
|
|
void LLLexer::Warning(LocTy WarningLoc, const Twine &Msg) const {
|
|
|
|
SM.PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
|
|
|
|
}
|
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Helper functions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// atoull - Convert an ascii string of decimal digits into the unsigned long
|
|
|
|
// long representation... this does not have to do input error checking,
|
|
|
|
// because we know that the input will be matched by a suitable regex...
|
|
|
|
//
|
2009-01-02 15:01:27 +08:00
|
|
|
uint64_t LLLexer::atoull(const char *Buffer, const char *End) {
|
2007-11-18 16:46:26 +08:00
|
|
|
uint64_t Result = 0;
|
|
|
|
for (; Buffer != End; Buffer++) {
|
|
|
|
uint64_t OldRes = Result;
|
|
|
|
Result *= 10;
|
|
|
|
Result += *Buffer-'0';
|
|
|
|
if (Result < OldRes) { // Uh, oh, overflow detected!!!
|
2009-01-02 15:01:27 +08:00
|
|
|
Error("constant bigger than 64 bits detected!");
|
2007-11-18 16:46:26 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) {
|
2007-11-18 16:46:26 +08:00
|
|
|
uint64_t Result = 0;
|
|
|
|
for (; Buffer != End; ++Buffer) {
|
|
|
|
uint64_t OldRes = Result;
|
|
|
|
Result *= 16;
|
2013-01-19 07:05:41 +08:00
|
|
|
Result += hexDigitValue(*Buffer);
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
if (Result < OldRes) { // Uh, oh, overflow detected!!!
|
2009-01-02 15:01:27 +08:00
|
|
|
Error("constant bigger than 64 bits detected!");
|
2007-11-18 16:46:26 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
void LLLexer::HexToIntPair(const char *Buffer, const char *End,
|
|
|
|
uint64_t Pair[2]) {
|
2007-11-18 16:46:26 +08:00
|
|
|
Pair[0] = 0;
|
2014-12-10 03:10:03 +08:00
|
|
|
if (End - Buffer >= 16) {
|
|
|
|
for (int i = 0; i < 16; i++, Buffer++) {
|
|
|
|
assert(Buffer != End);
|
|
|
|
Pair[0] *= 16;
|
|
|
|
Pair[0] += hexDigitValue(*Buffer);
|
|
|
|
}
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
Pair[1] = 0;
|
2014-12-10 03:10:03 +08:00
|
|
|
for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
|
2007-11-18 16:46:26 +08:00
|
|
|
Pair[1] *= 16;
|
2013-01-19 07:05:41 +08:00
|
|
|
Pair[1] += hexDigitValue(*Buffer);
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-11-19 02:25:18 +08:00
|
|
|
if (Buffer != End)
|
2009-01-02 15:01:27 +08:00
|
|
|
Error("constant bigger than 128 bits detected!");
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2009-03-24 05:16:53 +08:00
|
|
|
/// FP80HexToIntPair - translate an 80 bit FP80 number (20 hexits) into
|
|
|
|
/// { low64, high16 } as usual for an APInt.
|
|
|
|
void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,
|
|
|
|
uint64_t Pair[2]) {
|
|
|
|
Pair[1] = 0;
|
|
|
|
for (int i=0; i<4 && Buffer != End; i++, Buffer++) {
|
|
|
|
assert(Buffer != End);
|
|
|
|
Pair[1] *= 16;
|
2013-01-19 07:05:41 +08:00
|
|
|
Pair[1] += hexDigitValue(*Buffer);
|
2009-03-24 05:16:53 +08:00
|
|
|
}
|
|
|
|
Pair[0] = 0;
|
2015-09-01 05:36:14 +08:00
|
|
|
for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
|
2009-03-24 05:16:53 +08:00
|
|
|
Pair[0] *= 16;
|
2013-01-19 07:05:41 +08:00
|
|
|
Pair[0] += hexDigitValue(*Buffer);
|
2009-03-24 05:16:53 +08:00
|
|
|
}
|
|
|
|
if (Buffer != End)
|
|
|
|
Error("constant bigger than 128 bits detected!");
|
|
|
|
}
|
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
|
|
|
|
// appropriate character.
|
|
|
|
static void UnEscapeLexed(std::string &Str) {
|
|
|
|
if (Str.empty()) return;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
char *Buffer = &Str[0], *EndBuffer = Buffer+Str.size();
|
|
|
|
char *BOut = Buffer;
|
|
|
|
for (char *BIn = Buffer; BIn != EndBuffer; ) {
|
|
|
|
if (BIn[0] == '\\') {
|
|
|
|
if (BIn < EndBuffer-1 && BIn[1] == '\\') {
|
|
|
|
*BOut++ = '\\'; // Two \ becomes one
|
|
|
|
BIn += 2;
|
2013-02-13 05:21:59 +08:00
|
|
|
} else if (BIn < EndBuffer-2 &&
|
|
|
|
isxdigit(static_cast<unsigned char>(BIn[1])) &&
|
|
|
|
isxdigit(static_cast<unsigned char>(BIn[2]))) {
|
2013-01-19 07:05:41 +08:00
|
|
|
*BOut = hexDigitValue(BIn[1]) * 16 + hexDigitValue(BIn[2]);
|
2007-11-18 16:46:26 +08:00
|
|
|
BIn += 3; // Skip over handled chars
|
|
|
|
++BOut;
|
|
|
|
} else {
|
|
|
|
*BOut++ = *BIn++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*BOut++ = *BIn++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Str.resize(BOut-Buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isLabelChar - Return true for [-a-zA-Z$._0-9].
|
|
|
|
static bool isLabelChar(char C) {
|
2013-02-13 05:21:59 +08:00
|
|
|
return isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||
|
|
|
|
C == '.' || C == '_';
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// isLabelTail - Return true if this pointer points to a valid end of a label.
|
|
|
|
static const char *isLabelTail(const char *CurPtr) {
|
2016-08-19 01:56:27 +08:00
|
|
|
while (true) {
|
2007-11-18 16:46:26 +08:00
|
|
|
if (CurPtr[0] == ':') return CurPtr+1;
|
2014-04-15 14:32:26 +08:00
|
|
|
if (!isLabelChar(CurPtr[0])) return nullptr;
|
2007-11-18 16:46:26 +08:00
|
|
|
++CurPtr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Lexer definition.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2018-07-12 10:03:53 +08:00
|
|
|
LLLexer::LLLexer(StringRef StartBuf, SourceMgr &SM, SMDiagnostic &Err,
|
2009-07-08 02:44:11 +08:00
|
|
|
LLVMContext &C)
|
2018-07-12 10:03:53 +08:00
|
|
|
: CurBuf(StartBuf), ErrorInfo(Err), SM(SM), Context(C), APFloatVal(0.0),
|
2018-06-26 21:56:49 +08:00
|
|
|
IgnoreColonInIdentifiers(false) {
|
2014-08-19 06:28:28 +08:00
|
|
|
CurPtr = CurBuf.begin();
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int LLLexer::getNextChar() {
|
|
|
|
char CurChar = *CurPtr++;
|
|
|
|
switch (CurChar) {
|
|
|
|
default: return (unsigned char)CurChar;
|
|
|
|
case 0:
|
|
|
|
// A nul character in the stream is either the end of the current buffer or
|
|
|
|
// a random nul in the file. Disambiguate that here.
|
2014-08-19 06:28:28 +08:00
|
|
|
if (CurPtr-1 != CurBuf.end())
|
2007-11-18 16:46:26 +08:00
|
|
|
return 0; // Just whitespace.
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Otherwise, return end of file.
|
2007-12-16 17:16:12 +08:00
|
|
|
--CurPtr; // Another call to lex will return EOF again.
|
2007-11-18 16:46:26 +08:00
|
|
|
return EOF;
|
2007-12-16 17:16:12 +08:00
|
|
|
}
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
lltok::Kind LLLexer::LexToken() {
|
2016-11-17 06:25:05 +08:00
|
|
|
while (true) {
|
|
|
|
TokStart = CurPtr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2016-11-17 06:25:05 +08:00
|
|
|
int CurChar = getNextChar();
|
|
|
|
switch (CurChar) {
|
|
|
|
default:
|
|
|
|
// Handle letters: [a-zA-Z_]
|
|
|
|
if (isalpha(static_cast<unsigned char>(CurChar)) || CurChar == '_')
|
|
|
|
return LexIdentifier();
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2016-11-17 06:25:05 +08:00
|
|
|
return lltok::Error;
|
|
|
|
case EOF: return lltok::Eof;
|
|
|
|
case 0:
|
|
|
|
case ' ':
|
|
|
|
case '\t':
|
|
|
|
case '\n':
|
|
|
|
case '\r':
|
|
|
|
// Ignore whitespace.
|
|
|
|
continue;
|
|
|
|
case '+': return LexPositive();
|
|
|
|
case '@': return LexAt();
|
|
|
|
case '$': return LexDollar();
|
|
|
|
case '%': return LexPercent();
|
|
|
|
case '"': return LexQuote();
|
|
|
|
case '.':
|
|
|
|
if (const char *Ptr = isLabelTail(CurPtr)) {
|
|
|
|
CurPtr = Ptr;
|
|
|
|
StrVal.assign(TokStart, CurPtr-1);
|
|
|
|
return lltok::LabelStr;
|
|
|
|
}
|
|
|
|
if (CurPtr[0] == '.' && CurPtr[1] == '.') {
|
|
|
|
CurPtr += 2;
|
|
|
|
return lltok::dotdotdot;
|
|
|
|
}
|
|
|
|
return lltok::Error;
|
|
|
|
case ';':
|
|
|
|
SkipLineComment();
|
|
|
|
continue;
|
|
|
|
case '!': return LexExclaim();
|
2018-05-26 10:34:13 +08:00
|
|
|
case '^':
|
|
|
|
return LexCaret();
|
2018-06-26 21:56:49 +08:00
|
|
|
case ':':
|
|
|
|
return lltok::colon;
|
2016-11-17 06:25:05 +08:00
|
|
|
case '#': return LexHash();
|
|
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
|
|
case '-':
|
|
|
|
return LexDigitOrNegative();
|
|
|
|
case '=': return lltok::equal;
|
|
|
|
case '[': return lltok::lsquare;
|
|
|
|
case ']': return lltok::rsquare;
|
|
|
|
case '{': return lltok::lbrace;
|
|
|
|
case '}': return lltok::rbrace;
|
|
|
|
case '<': return lltok::less;
|
|
|
|
case '>': return lltok::greater;
|
|
|
|
case '(': return lltok::lparen;
|
|
|
|
case ')': return lltok::rparen;
|
|
|
|
case ',': return lltok::comma;
|
|
|
|
case '*': return lltok::star;
|
|
|
|
case '|': return lltok::bar;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLLexer::SkipLineComment() {
|
2016-08-19 01:56:27 +08:00
|
|
|
while (true) {
|
2007-11-18 16:46:26 +08:00
|
|
|
if (CurPtr[0] == '\n' || CurPtr[0] == '\r' || getNextChar() == EOF)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex all tokens that start with an @ character.
|
2009-01-02 15:01:27 +08:00
|
|
|
/// GlobalVar @\"[^\"]*\"
|
|
|
|
/// GlobalVar @[-a-zA-Z$._][-a-zA-Z$._0-9]*
|
|
|
|
/// GlobalVarID @[0-9]+
|
|
|
|
lltok::Kind LLLexer::LexAt() {
|
2014-12-10 08:43:17 +08:00
|
|
|
return LexVar(lltok::GlobalVar, lltok::GlobalID);
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2014-06-28 02:19:56 +08:00
|
|
|
lltok::Kind LLLexer::LexDollar() {
|
|
|
|
if (const char *Ptr = isLabelTail(TokStart)) {
|
|
|
|
CurPtr = Ptr;
|
|
|
|
StrVal.assign(TokStart, CurPtr - 1);
|
|
|
|
return lltok::LabelStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle DollarStringConstant: $\"[^\"]*\"
|
|
|
|
if (CurPtr[0] == '"') {
|
|
|
|
++CurPtr;
|
|
|
|
|
2016-08-19 01:56:27 +08:00
|
|
|
while (true) {
|
2014-06-28 02:19:56 +08:00
|
|
|
int CurChar = getNextChar();
|
|
|
|
|
|
|
|
if (CurChar == EOF) {
|
|
|
|
Error("end of file in COMDAT variable name");
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
if (CurChar == '"') {
|
|
|
|
StrVal.assign(TokStart + 2, CurPtr - 1);
|
|
|
|
UnEscapeLexed(StrVal);
|
|
|
|
if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
|
|
|
|
Error("Null bytes are not allowed in names");
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
return lltok::ComdatVar;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle ComdatVarName: $[-a-zA-Z$._][-a-zA-Z$._0-9]*
|
|
|
|
if (ReadVarName())
|
|
|
|
return lltok::ComdatVar;
|
|
|
|
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
|
2011-06-05 02:16:26 +08:00
|
|
|
/// ReadString - Read a string until the closing quote.
|
|
|
|
lltok::Kind LLLexer::ReadString(lltok::Kind kind) {
|
|
|
|
const char *Start = CurPtr;
|
2016-08-19 01:56:27 +08:00
|
|
|
while (true) {
|
2011-06-05 02:16:26 +08:00
|
|
|
int CurChar = getNextChar();
|
|
|
|
|
|
|
|
if (CurChar == EOF) {
|
|
|
|
Error("end of file in string constant");
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
if (CurChar == '"') {
|
|
|
|
StrVal.assign(Start, CurPtr-1);
|
|
|
|
UnEscapeLexed(StrVal);
|
|
|
|
return kind;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ReadVarName - Read the rest of a token containing a variable name.
|
|
|
|
bool LLLexer::ReadVarName() {
|
|
|
|
const char *NameStart = CurPtr;
|
2013-02-13 05:21:59 +08:00
|
|
|
if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
|
|
|
|
CurPtr[0] == '-' || CurPtr[0] == '$' ||
|
2011-06-05 02:16:26 +08:00
|
|
|
CurPtr[0] == '.' || CurPtr[0] == '_') {
|
|
|
|
++CurPtr;
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
|
|
|
|
CurPtr[0] == '-' || CurPtr[0] == '$' ||
|
2011-06-05 02:16:26 +08:00
|
|
|
CurPtr[0] == '.' || CurPtr[0] == '_')
|
|
|
|
++CurPtr;
|
|
|
|
|
|
|
|
StrVal.assign(NameStart, CurPtr);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2007-11-18 16:46:26 +08:00
|
|
|
|
2018-05-26 10:34:13 +08:00
|
|
|
// Lex an ID: [0-9]+. On success, the ID is stored in UIntVal and Token is
|
|
|
|
// returned, otherwise the Error token is returned.
|
|
|
|
lltok::Kind LLLexer::LexUIntID(lltok::Kind Token) {
|
|
|
|
if (!isdigit(static_cast<unsigned char>(CurPtr[0])))
|
|
|
|
return lltok::Error;
|
|
|
|
|
|
|
|
for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
|
|
|
|
/*empty*/;
|
|
|
|
|
|
|
|
uint64_t Val = atoull(TokStart + 1, CurPtr);
|
|
|
|
if ((unsigned)Val != Val)
|
|
|
|
Error("invalid value number (too large)!");
|
|
|
|
UIntVal = unsigned(Val);
|
|
|
|
return Token;
|
|
|
|
}
|
|
|
|
|
2014-12-10 08:43:17 +08:00
|
|
|
lltok::Kind LLLexer::LexVar(lltok::Kind Var, lltok::Kind VarID) {
|
|
|
|
// Handle StringConstant: \"[^\"]*\"
|
2007-11-18 16:46:26 +08:00
|
|
|
if (CurPtr[0] == '"') {
|
|
|
|
++CurPtr;
|
2014-12-10 08:43:17 +08:00
|
|
|
|
2016-08-19 01:56:27 +08:00
|
|
|
while (true) {
|
2014-12-10 08:43:17 +08:00
|
|
|
int CurChar = getNextChar();
|
|
|
|
|
|
|
|
if (CurChar == EOF) {
|
|
|
|
Error("end of file in global variable name");
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
if (CurChar == '"') {
|
|
|
|
StrVal.assign(TokStart+2, CurPtr-1);
|
|
|
|
UnEscapeLexed(StrVal);
|
|
|
|
if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
|
|
|
|
Error("Null bytes are not allowed in names");
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
return Var;
|
|
|
|
}
|
|
|
|
}
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2014-12-10 08:43:17 +08:00
|
|
|
// Handle VarName: [-a-zA-Z$._][-a-zA-Z$._0-9]*
|
2011-06-05 02:16:26 +08:00
|
|
|
if (ReadVarName())
|
2014-12-10 08:43:17 +08:00
|
|
|
return Var;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2014-12-10 08:43:17 +08:00
|
|
|
// Handle VarID: [0-9]+
|
2018-05-26 10:34:13 +08:00
|
|
|
return LexUIntID(VarID);
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex all tokens that start with a % character.
|
2014-12-10 08:43:17 +08:00
|
|
|
/// LocalVar ::= %\"[^\"]*\"
|
|
|
|
/// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]*
|
|
|
|
/// LocalVarID ::= %[0-9]+
|
|
|
|
lltok::Kind LLLexer::LexPercent() {
|
|
|
|
return LexVar(lltok::LocalVar, lltok::LocalVarID);
|
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex all tokens that start with a " character.
|
2007-11-18 16:46:26 +08:00
|
|
|
/// QuoteLabel "[^"]+":
|
|
|
|
/// StringConstant "[^"]*"
|
2009-01-02 15:01:27 +08:00
|
|
|
lltok::Kind LLLexer::LexQuote() {
|
2011-06-05 02:16:26 +08:00
|
|
|
lltok::Kind kind = ReadString(lltok::StringConstant);
|
|
|
|
if (kind == lltok::Error || kind == lltok::Eof)
|
|
|
|
return kind;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2011-06-05 02:16:26 +08:00
|
|
|
if (CurPtr[0] == ':') {
|
2007-11-18 16:46:26 +08:00
|
|
|
++CurPtr;
|
2014-12-10 10:10:35 +08:00
|
|
|
if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
|
|
|
|
Error("Null bytes are not allowed in names");
|
|
|
|
kind = lltok::Error;
|
|
|
|
} else {
|
|
|
|
kind = lltok::LabelStr;
|
|
|
|
}
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2011-06-05 02:16:26 +08:00
|
|
|
|
|
|
|
return kind;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex all tokens that start with a ! character.
|
2009-07-29 08:34:02 +08:00
|
|
|
/// !foo
|
2009-12-30 13:02:06 +08:00
|
|
|
/// !
|
2009-12-30 12:56:59 +08:00
|
|
|
lltok::Kind LLLexer::LexExclaim() {
|
2009-12-30 13:02:06 +08:00
|
|
|
// Lex a metadata name as a MetadataVar.
|
2013-02-13 05:21:59 +08:00
|
|
|
if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
|
|
|
|
CurPtr[0] == '-' || CurPtr[0] == '$' ||
|
2011-06-15 14:37:58 +08:00
|
|
|
CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') {
|
2009-07-29 08:34:02 +08:00
|
|
|
++CurPtr;
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
|
|
|
|
CurPtr[0] == '-' || CurPtr[0] == '$' ||
|
2011-06-15 14:37:58 +08:00
|
|
|
CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\')
|
2009-07-29 08:34:02 +08:00
|
|
|
++CurPtr;
|
2007-11-18 16:46:26 +08:00
|
|
|
|
2009-07-29 08:34:02 +08:00
|
|
|
StrVal.assign(TokStart+1, CurPtr); // Skip !
|
2011-06-15 14:37:58 +08:00
|
|
|
UnEscapeLexed(StrVal);
|
2009-12-30 13:02:06 +08:00
|
|
|
return lltok::MetadataVar;
|
2009-07-29 08:34:02 +08:00
|
|
|
}
|
2009-12-30 12:56:59 +08:00
|
|
|
return lltok::exclaim;
|
2009-07-29 08:34:02 +08:00
|
|
|
}
|
2012-11-27 08:42:44 +08:00
|
|
|
|
2018-05-26 10:34:13 +08:00
|
|
|
/// Lex all tokens that start with a ^ character.
|
|
|
|
/// SummaryID ::= ^[0-9]+
|
|
|
|
lltok::Kind LLLexer::LexCaret() {
|
|
|
|
// Handle SummaryID: ^[0-9]+
|
|
|
|
return LexUIntID(lltok::SummaryID);
|
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex all tokens that start with a # character.
|
2013-02-06 14:52:58 +08:00
|
|
|
/// AttrGrpID ::= #[0-9]+
|
|
|
|
lltok::Kind LLLexer::LexHash() {
|
|
|
|
// Handle AttrGrpID: #[0-9]+
|
2018-05-26 10:34:13 +08:00
|
|
|
return LexUIntID(lltok::AttrGrpID);
|
2013-02-06 14:52:58 +08:00
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex a label, integer type, keyword, or hexadecimal integer constant.
|
2007-11-18 16:46:26 +08:00
|
|
|
/// Label [-a-zA-Z$._0-9]+:
|
|
|
|
/// IntegerType i[0-9]+
|
|
|
|
/// Keyword sdiv, float, ...
|
|
|
|
/// HexIntConstant [us]0x[0-9A-Fa-f]+
|
2009-01-02 15:01:27 +08:00
|
|
|
lltok::Kind LLLexer::LexIdentifier() {
|
2007-11-18 16:46:26 +08:00
|
|
|
const char *StartChar = CurPtr;
|
2014-04-15 14:32:26 +08:00
|
|
|
const char *IntEnd = CurPtr[-1] == 'i' ? nullptr : StartChar;
|
|
|
|
const char *KeywordEnd = nullptr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
for (; isLabelChar(*CurPtr); ++CurPtr) {
|
|
|
|
// If we decide this is an integer, remember the end of the sequence.
|
2013-02-13 05:21:59 +08:00
|
|
|
if (!IntEnd && !isdigit(static_cast<unsigned char>(*CurPtr)))
|
|
|
|
IntEnd = CurPtr;
|
|
|
|
if (!KeywordEnd && !isalnum(static_cast<unsigned char>(*CurPtr)) &&
|
|
|
|
*CurPtr != '_')
|
|
|
|
KeywordEnd = CurPtr;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2018-06-26 21:56:49 +08:00
|
|
|
// If we stopped due to a colon, unless we were directed to ignore it,
|
|
|
|
// this really is a label.
|
|
|
|
if (!IgnoreColonInIdentifiers && *CurPtr == ':') {
|
2009-01-02 15:01:27 +08:00
|
|
|
StrVal.assign(StartChar-1, CurPtr++);
|
|
|
|
return lltok::LabelStr;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Otherwise, this wasn't a label. If this was valid as an integer type,
|
|
|
|
// return it.
|
2014-04-15 14:32:26 +08:00
|
|
|
if (!IntEnd) IntEnd = CurPtr;
|
2007-11-18 16:46:26 +08:00
|
|
|
if (IntEnd != StartChar) {
|
|
|
|
CurPtr = IntEnd;
|
|
|
|
uint64_t NumBits = atoull(StartChar, CurPtr);
|
2007-12-16 17:16:12 +08:00
|
|
|
if (NumBits < IntegerType::MIN_INT_BITS ||
|
2007-11-18 16:46:26 +08:00
|
|
|
NumBits > IntegerType::MAX_INT_BITS) {
|
2009-01-02 15:01:27 +08:00
|
|
|
Error("bitwidth for integer type out of range!");
|
|
|
|
return lltok::Error;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2009-08-14 05:58:54 +08:00
|
|
|
TyVal = IntegerType::get(Context, NumBits);
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::Type;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Otherwise, this was a letter sequence. See which keyword this is.
|
2014-04-15 14:32:26 +08:00
|
|
|
if (!KeywordEnd) KeywordEnd = CurPtr;
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr = KeywordEnd;
|
|
|
|
--StartChar;
|
2015-02-21 08:18:40 +08:00
|
|
|
StringRef Keyword(StartChar, CurPtr - StartChar);
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2015-02-21 08:18:40 +08:00
|
|
|
#define KEYWORD(STR) \
|
|
|
|
do { \
|
|
|
|
if (Keyword == #STR) \
|
|
|
|
return lltok::kw_##STR; \
|
2016-08-19 01:56:27 +08:00
|
|
|
} while (false)
|
2009-01-02 15:01:27 +08:00
|
|
|
|
|
|
|
KEYWORD(true); KEYWORD(false);
|
|
|
|
KEYWORD(declare); KEYWORD(define);
|
|
|
|
KEYWORD(global); KEYWORD(constant);
|
|
|
|
|
2017-10-26 23:00:26 +08:00
|
|
|
KEYWORD(dso_local);
|
|
|
|
KEYWORD(dso_preemptable);
|
|
|
|
|
2009-01-16 04:18:42 +08:00
|
|
|
KEYWORD(private);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(internal);
|
2009-04-13 13:44:34 +08:00
|
|
|
KEYWORD(available_externally);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(linkonce);
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
llvm-svn: 66339
2009-03-07 23:45:40 +08:00
|
|
|
KEYWORD(linkonce_odr);
|
IR: add "cmpxchg weak" variant to support permitted failure.
This commit adds a weak variant of the cmpxchg operation, as described
in C++11. A cmpxchg instruction with this modifier is permitted to
fail to store, even if the comparison indicated it should.
As a result, cmpxchg instructions must return a flag indicating
success in addition to their original iN value loaded. Thus, for
uniformity *all* cmpxchg instructions now return "{ iN, i1 }". The
second flag is 1 when the store succeeded.
At the DAG level, a new ATOMIC_CMP_SWAP_WITH_SUCCESS node has been
added as the natural representation for the new cmpxchg instructions.
It is a strong cmpxchg.
By default this gets Expanded to the existing ATOMIC_CMP_SWAP during
Legalization, so existing backends should see no change in behaviour.
If they wish to deal with the enhanced node instead, they can call
setOperationAction on it. Beware: as a node with 2 results, it cannot
be selected from TableGen.
Currently, no use is made of the extra information provided in this
patch. Test updates are almost entirely adapting the input IR to the
new scheme.
Summary for out of tree users:
------------------------------
+ Legacy Bitcode files are upgraded during read.
+ Legacy assembly IR files will be invalid.
+ Front-ends must adapt to different type for "cmpxchg".
+ Backends should be unaffected by default.
llvm-svn: 210903
2014-06-13 22:24:07 +08:00
|
|
|
KEYWORD(weak); // Use as a linkage, and a modifier for "cmpxchg".
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
llvm-svn: 66339
2009-03-07 23:45:40 +08:00
|
|
|
KEYWORD(weak_odr);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(appending);
|
|
|
|
KEYWORD(dllimport);
|
|
|
|
KEYWORD(dllexport);
|
|
|
|
KEYWORD(common);
|
|
|
|
KEYWORD(default);
|
|
|
|
KEYWORD(hidden);
|
|
|
|
KEYWORD(protected);
|
2011-01-09 00:42:36 +08:00
|
|
|
KEYWORD(unnamed_addr);
|
2016-06-15 05:01:22 +08:00
|
|
|
KEYWORD(local_unnamed_addr);
|
2013-02-05 13:57:38 +08:00
|
|
|
KEYWORD(externally_initialized);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(extern_weak);
|
|
|
|
KEYWORD(external);
|
|
|
|
KEYWORD(thread_local);
|
2012-06-23 19:37:03 +08:00
|
|
|
KEYWORD(localdynamic);
|
|
|
|
KEYWORD(initialexec);
|
|
|
|
KEYWORD(localexec);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(zeroinitializer);
|
|
|
|
KEYWORD(undef);
|
|
|
|
KEYWORD(null);
|
2015-11-12 05:57:16 +08:00
|
|
|
KEYWORD(none);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(to);
|
2015-08-01 01:58:14 +08:00
|
|
|
KEYWORD(caller);
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
KEYWORD(within);
|
|
|
|
KEYWORD(from);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(tail);
|
2014-04-25 04:14:34 +08:00
|
|
|
KEYWORD(musttail);
|
2015-11-07 07:55:38 +08:00
|
|
|
KEYWORD(notail);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(target);
|
|
|
|
KEYWORD(triple);
|
2016-03-31 02:15:08 +08:00
|
|
|
KEYWORD(source_filename);
|
2012-02-07 05:02:43 +08:00
|
|
|
KEYWORD(unwind);
|
2012-11-28 16:41:48 +08:00
|
|
|
KEYWORD(deplibs); // FIXME: Remove in 4.0.
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(datalayout);
|
|
|
|
KEYWORD(volatile);
|
2011-07-26 07:16:38 +08:00
|
|
|
KEYWORD(atomic);
|
|
|
|
KEYWORD(unordered);
|
|
|
|
KEYWORD(monotonic);
|
|
|
|
KEYWORD(acquire);
|
|
|
|
KEYWORD(release);
|
|
|
|
KEYWORD(acq_rel);
|
|
|
|
KEYWORD(seq_cst);
|
2017-07-12 06:23:00 +08:00
|
|
|
KEYWORD(syncscope);
|
2011-07-26 07:16:38 +08:00
|
|
|
|
2013-02-05 15:19:31 +08:00
|
|
|
KEYWORD(nnan);
|
|
|
|
KEYWORD(ninf);
|
|
|
|
KEYWORD(nsz);
|
|
|
|
KEYWORD(arcp);
|
2017-03-29 04:11:52 +08:00
|
|
|
KEYWORD(contract);
|
[IR] redefine 'UnsafeAlgebra' / 'reassoc' fast-math-flags and add 'trans' fast-math-flag
As discussed on llvm-dev:
http://lists.llvm.org/pipermail/llvm-dev/2016-November/107104.html
and again more recently:
http://lists.llvm.org/pipermail/llvm-dev/2017-October/118118.html
...this is a step in cleaning up our fast-math-flags implementation in IR to better match
the capabilities of both clang's user-visible flags and the backend's flags for SDNode.
As proposed in the above threads, we're replacing the 'UnsafeAlgebra' bit (which had the
'umbrella' meaning that all flags are set) with a new bit that only applies to algebraic
reassociation - 'AllowReassoc'.
We're also adding a bit to allow approximations for library functions called 'ApproxFunc'
(this was initially proposed as 'libm' or similar).
...and we're out of bits. 7 bits ought to be enough for anyone, right? :) FWIW, I did
look at getting this out of SubclassOptionalData via SubclassData (spacious 16-bits),
but that's apparently already used for other purposes. Also, I don't think we can just
add a field to FPMathOperator because Operator is not intended to be instantiated.
We'll defer movement of FMF to another day.
We keep the 'fast' keyword. I thought about removing that, but seeing IR like this:
%f.fast = fadd reassoc nnan ninf nsz arcp contract afn float %op1, %op2
...made me think we want to keep the shortcut synonym.
Finally, this change is binary incompatible with existing IR as seen in the
compatibility tests. This statement:
"Newer releases can ignore features from older releases, but they cannot miscompile
them. For example, if nsw is ever replaced with something else, dropping it would be
a valid way to upgrade the IR."
( http://llvm.org/docs/DeveloperPolicy.html#ir-backwards-compatibility )
...provides the flexibility we want to make this change without requiring a new IR
version. Ie, we're not loosening the FP strictness of existing IR. At worst, we will
fail to optimize some previously 'fast' code because it's no longer recognized as
'fast'. This should get fixed as we audit/squash all of the uses of 'isFast()'.
Note: an inter-dependent clang commit to use the new API name should closely follow
commit.
Differential Revision: https://reviews.llvm.org/D39304
llvm-svn: 317488
2017-11-07 00:27:15 +08:00
|
|
|
KEYWORD(reassoc);
|
|
|
|
KEYWORD(afn);
|
2013-02-05 15:19:31 +08:00
|
|
|
KEYWORD(fast);
|
2009-07-23 06:44:56 +08:00
|
|
|
KEYWORD(nuw);
|
|
|
|
KEYWORD(nsw);
|
2009-07-21 05:19:07 +08:00
|
|
|
KEYWORD(exact);
|
2009-07-28 05:53:46 +08:00
|
|
|
KEYWORD(inbounds);
|
2016-11-11 06:34:55 +08:00
|
|
|
KEYWORD(inrange);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(align);
|
|
|
|
KEYWORD(addrspace);
|
|
|
|
KEYWORD(section);
|
2019-05-29 11:29:01 +08:00
|
|
|
KEYWORD(partition);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(alias);
|
2016-04-07 20:32:19 +08:00
|
|
|
KEYWORD(ifunc);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(module);
|
|
|
|
KEYWORD(asm);
|
|
|
|
KEYWORD(sideeffect);
|
2009-10-22 07:28:00 +08:00
|
|
|
KEYWORD(alignstack);
|
2012-09-06 03:00:49 +08:00
|
|
|
KEYWORD(inteldialect);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(gc);
|
2013-09-16 09:08:15 +08:00
|
|
|
KEYWORD(prefix);
|
2014-12-03 10:08:38 +08:00
|
|
|
KEYWORD(prologue);
|
2009-01-02 15:01:27 +08:00
|
|
|
|
|
|
|
KEYWORD(ccc);
|
|
|
|
KEYWORD(fastcc);
|
|
|
|
KEYWORD(coldcc);
|
Add Windows Control Flow Guard checks (/guard:cf).
Summary:
A new function pass (Transforms/CFGuard/CFGuard.cpp) inserts CFGuard checks on
indirect function calls, using either the check mechanism (X86, ARM, AArch64) or
or the dispatch mechanism (X86-64). The check mechanism requires a new calling
convention for the supported targets. The dispatch mechanism adds the target as
an operand bundle, which is processed by SelectionDAG. Another pass
(CodeGen/CFGuardLongjmp.cpp) identifies and emits valid longjmp targets, as
required by /guard:cf. This feature is enabled using the `cfguard` CC1 option.
Reviewers: thakis, rnk, theraven, pcc
Subscribers: ychen, hans, metalcanine, dmajor, tomrittervg, alex, mehdi_amini, mgorny, javed.absar, kristof.beyls, hiraditya, steven_wu, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D65761
2019-10-28 21:22:19 +08:00
|
|
|
KEYWORD(cfguard_checkcc);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(x86_stdcallcc);
|
|
|
|
KEYWORD(x86_fastcallcc);
|
2010-05-16 17:08:45 +08:00
|
|
|
KEYWORD(x86_thiscallcc);
|
2014-10-28 09:29:26 +08:00
|
|
|
KEYWORD(x86_vectorcallcc);
|
2009-06-17 02:50:49 +08:00
|
|
|
KEYWORD(arm_apcscc);
|
|
|
|
KEYWORD(arm_aapcscc);
|
|
|
|
KEYWORD(arm_aapcs_vfpcc);
|
2018-09-12 16:54:06 +08:00
|
|
|
KEYWORD(aarch64_vector_pcs);
|
2019-11-06 00:54:54 +08:00
|
|
|
KEYWORD(aarch64_sve_vector_pcs);
|
2009-12-07 10:27:35 +08:00
|
|
|
KEYWORD(msp430_intrcc);
|
2016-03-03 18:08:02 +08:00
|
|
|
KEYWORD(avr_intrcc);
|
|
|
|
KEYWORD(avr_signalcc);
|
2010-09-25 15:46:17 +08:00
|
|
|
KEYWORD(ptx_kernel);
|
|
|
|
KEYWORD(ptx_device);
|
2012-10-02 01:01:31 +08:00
|
|
|
KEYWORD(spir_kernel);
|
|
|
|
KEYWORD(spir_func);
|
2012-10-24 22:46:16 +08:00
|
|
|
KEYWORD(intel_ocl_bicc);
|
2013-07-12 14:02:35 +08:00
|
|
|
KEYWORD(x86_64_sysvcc);
|
2017-07-18 04:05:19 +08:00
|
|
|
KEYWORD(win64cc);
|
2016-10-13 15:53:43 +08:00
|
|
|
KEYWORD(x86_regcallcc);
|
2013-11-01 06:12:01 +08:00
|
|
|
KEYWORD(webkit_jscc);
|
2016-04-06 06:41:47 +08:00
|
|
|
KEYWORD(swiftcc);
|
2013-11-09 07:28:16 +08:00
|
|
|
KEYWORD(anyregcc);
|
2014-01-18 03:47:03 +08:00
|
|
|
KEYWORD(preserve_mostcc);
|
|
|
|
KEYWORD(preserve_allcc);
|
2014-12-02 05:04:44 +08:00
|
|
|
KEYWORD(ghccc);
|
2015-12-21 22:07:14 +08:00
|
|
|
KEYWORD(x86_intrcc);
|
HHVM calling conventions.
HHVM calling convention, hhvmcc, is used by HHVM JIT for
functions in translated cache. We currently support LLVM back end to
generate code for X86-64 and may support other architectures in the
future.
In HHVM calling convention any GP register could be used to pass and
return values, with the exception of R12 which is reserved for
thread-local area and is callee-saved. Other than R12, we always
pass RBX and RBP as args, which are our virtual machine's stack pointer
and frame pointer respectively.
When we enter translation cache via hhvmcc function, we expect
the stack to be aligned at 16 bytes, i.e. skewed by 8 bytes as opposed
to standard ABI alignment. This affects stack object alignment and stack
adjustments for function calls.
One extra calling convention, hhvm_ccc, is used to call C++ helpers from
HHVM's translation cache. It is almost identical to standard C calling
convention with an exception of first argument which is passed in RBP
(before we use RDI, RSI, etc.)
Differential Revision: http://reviews.llvm.org/D12681
llvm-svn: 248832
2015-09-30 06:09:16 +08:00
|
|
|
KEYWORD(hhvmcc);
|
|
|
|
KEYWORD(hhvm_ccc);
|
2015-12-05 01:40:13 +08:00
|
|
|
KEYWORD(cxx_fast_tlscc);
|
2016-04-07 03:40:20 +08:00
|
|
|
KEYWORD(amdgpu_vs);
|
2017-09-29 17:51:22 +08:00
|
|
|
KEYWORD(amdgpu_ls);
|
2017-05-02 23:41:10 +08:00
|
|
|
KEYWORD(amdgpu_hs);
|
2017-09-29 17:51:22 +08:00
|
|
|
KEYWORD(amdgpu_es);
|
2016-04-07 03:40:20 +08:00
|
|
|
KEYWORD(amdgpu_gs);
|
|
|
|
KEYWORD(amdgpu_ps);
|
|
|
|
KEYWORD(amdgpu_cs);
|
2016-05-06 17:07:29 +08:00
|
|
|
KEYWORD(amdgpu_kernel);
|
2019-10-08 06:28:58 +08:00
|
|
|
KEYWORD(tailcc);
|
2009-06-17 02:50:49 +08:00
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(cc);
|
|
|
|
KEYWORD(c);
|
|
|
|
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(attributes);
|
|
|
|
|
|
|
|
KEYWORD(alwaysinline);
|
2016-04-12 09:05:35 +08:00
|
|
|
KEYWORD(allocsize);
|
2015-07-11 18:30:36 +08:00
|
|
|
KEYWORD(argmemonly);
|
2013-06-27 08:25:01 +08:00
|
|
|
KEYWORD(builtin);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(byval);
|
2013-12-19 10:14:12 +08:00
|
|
|
KEYWORD(inalloca);
|
2013-05-24 20:26:52 +08:00
|
|
|
KEYWORD(cold);
|
2015-05-27 07:48:40 +08:00
|
|
|
KEYWORD(convergent);
|
2014-07-18 23:51:28 +08:00
|
|
|
KEYWORD(dereferenceable);
|
2015-04-17 04:29:50 +08:00
|
|
|
KEYWORD(dereferenceable_or_null);
|
2015-12-17 00:16:19 +08:00
|
|
|
KEYWORD(inaccessiblememonly);
|
|
|
|
KEYWORD(inaccessiblemem_or_argmemonly);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(inlinehint);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(inreg);
|
2014-06-06 03:29:43 +08:00
|
|
|
KEYWORD(jumptable);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(minsize);
|
|
|
|
KEYWORD(naked);
|
|
|
|
KEYWORD(nest);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(noalias);
|
2013-02-22 08:12:35 +08:00
|
|
|
KEYWORD(nobuiltin);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(nocapture);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(noduplicate);
|
2019-07-08 23:57:56 +08:00
|
|
|
KEYWORD(nofree);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(noimplicitfloat);
|
|
|
|
KEYWORD(noinline);
|
2015-11-06 18:32:53 +08:00
|
|
|
KEYWORD(norecurse);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(nonlazybind);
|
2020-05-13 05:07:50 +08:00
|
|
|
KEYWORD(nomerge);
|
2014-05-20 09:23:40 +08:00
|
|
|
KEYWORD(nonnull);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(noredzone);
|
|
|
|
KEYWORD(noreturn);
|
[Attributor] Deduce "nosync" function attribute.
Introduce and deduce "nosync" function attribute to indicate that a function
does not synchronize with another thread in a way that other thread might free memory.
Reviewers: jdoerfert, jfb, nhaehnle, arsenm
Subscribers: wdng, hfinkel, nhaenhle, mehdi_amini, steven_wu,
dexonsmith, arsenm, uenoku, hiraditya, jfb, llvm-commits
Differential Revision: https://reviews.llvm.org/D62766
llvm-svn: 365830
2019-07-12 05:37:40 +08:00
|
|
|
KEYWORD(nosync);
|
2018-03-17 21:29:46 +08:00
|
|
|
KEYWORD(nocf_check);
|
2020-07-09 01:22:48 +08:00
|
|
|
KEYWORD(noundef);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(nounwind);
|
2020-04-25 18:57:07 +08:00
|
|
|
KEYWORD(null_pointer_is_valid);
|
[SimplifyCFG] Create attribute for fuzzing-specific optimizations.
Summary:
When building with libFuzzer, converting control flow to selects or
obscuring the original operands of CMPs reduces the effectiveness of
libFuzzer's heuristics.
This patch provides an attribute to disable or modify certain optimizations
for optimal fuzzing signal.
Provides a less aggressive alternative to https://reviews.llvm.org/D44057.
Reviewers: vitalybuka, davide, arsenm, hfinkel
Reviewed By: vitalybuka
Subscribers: junbuml, mehdi_amini, wdng, javed.absar, hiraditya, llvm-commits, kcc
Differential Revision: https://reviews.llvm.org/D44232
llvm-svn: 328214
2018-03-23 01:07:51 +08:00
|
|
|
KEYWORD(optforfuzzing);
|
2013-08-23 19:53:55 +08:00
|
|
|
KEYWORD(optnone);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(optsize);
|
2020-02-15 06:16:53 +08:00
|
|
|
KEYWORD(preallocated);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(readnone);
|
|
|
|
KEYWORD(readonly);
|
2013-04-20 13:14:40 +08:00
|
|
|
KEYWORD(returned);
|
2011-10-03 22:45:37 +08:00
|
|
|
KEYWORD(returns_twice);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(signext);
|
2017-04-29 04:25:27 +08:00
|
|
|
KEYWORD(speculatable);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(sret);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(ssp);
|
|
|
|
KEYWORD(sspreq);
|
2013-01-23 14:41:41 +08:00
|
|
|
KEYWORD(sspstrong);
|
2017-08-15 05:15:13 +08:00
|
|
|
KEYWORD(strictfp);
|
Protection against stack-based memory corruption errors using SafeStack
This patch adds the safe stack instrumentation pass to LLVM, which separates
the program stack into a safe stack, which stores return addresses, register
spills, and local variables that are statically verified to be accessed
in a safe way, and the unsafe stack, which stores everything else. Such
separation makes it much harder for an attacker to corrupt objects on the
safe stack, including function pointers stored in spilled registers and
return addresses. You can find more information about the safe stack, as
well as other parts of or control-flow hijack protection technique in our
OSDI paper on code-pointer integrity (http://dslab.epfl.ch/pubs/cpi.pdf)
and our project website (http://levee.epfl.ch).
The overhead of our implementation of the safe stack is very close to zero
(0.01% on the Phoronix benchmarks). This is lower than the overhead of
stack cookies, which are supported by LLVM and are commonly used today,
yet the security guarantees of the safe stack are strictly stronger than
stack cookies. In some cases, the safe stack improves performance due to
better cache locality.
Our current implementation of the safe stack is stable and robust, we
used it to recompile multiple projects on Linux including Chromium, and
we also recompiled the entire FreeBSD user-space system and more than 100
packages. We ran unit tests on the FreeBSD system and many of the packages
and observed no errors caused by the safe stack. The safe stack is also fully
binary compatible with non-instrumented code and can be applied to parts of
a program selectively.
This patch is our implementation of the safe stack on top of LLVM. The
patches make the following changes:
- Add the safestack function attribute, similar to the ssp, sspstrong and
sspreq attributes.
- Add the SafeStack instrumentation pass that applies the safe stack to all
functions that have the safestack attribute. This pass moves all unsafe local
variables to the unsafe stack with a separate stack pointer, whereas all
safe variables remain on the regular stack that is managed by LLVM as usual.
- Invoke the pass as the last stage before code generation (at the same time
the existing cookie-based stack protector pass is invoked).
- Add unit tests for the safe stack.
Original patch by Volodymyr Kuznetsov and others at the Dependable Systems
Lab at EPFL; updates and upstreaming by myself.
Differential Revision: http://reviews.llvm.org/D6094
llvm-svn: 239761
2015-06-16 05:07:11 +08:00
|
|
|
KEYWORD(safestack);
|
2018-04-04 04:10:40 +08:00
|
|
|
KEYWORD(shadowcallstack);
|
2013-02-26 14:58:09 +08:00
|
|
|
KEYWORD(sanitize_address);
|
2017-12-09 08:21:41 +08:00
|
|
|
KEYWORD(sanitize_hwaddress);
|
ARM MTE stack sanitizer.
Add "memtag" sanitizer that detects and mitigates stack memory issues
using armv8.5 Memory Tagging Extension.
It is similar in principle to HWASan, which is a software implementation
of the same idea, but there are enough differencies to warrant a new
sanitizer type IMHO. It is also expected to have very different
performance properties.
The new sanitizer does not have a runtime library (it may grow one
later, along with a "debugging" mode). Similar to SafeStack and
StackProtector, the instrumentation pass (in a follow up change) will be
inserted in all cases, but will only affect functions marked with the
new sanitize_memtag attribute.
Reviewers: pcc, hctim, vitalybuka, ostannard
Subscribers: srhines, mehdi_amini, javed.absar, kristof.beyls, hiraditya, cryptoad, steven_wu, dexonsmith, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D64169
llvm-svn: 366123
2019-07-16 04:02:23 +08:00
|
|
|
KEYWORD(sanitize_memtag);
|
2013-02-26 14:58:09 +08:00
|
|
|
KEYWORD(sanitize_thread);
|
|
|
|
KEYWORD(sanitize_memory);
|
2018-09-04 20:38:00 +08:00
|
|
|
KEYWORD(speculative_load_hardening);
|
2016-04-02 05:41:15 +08:00
|
|
|
KEYWORD(swifterror);
|
2016-03-30 01:37:21 +08:00
|
|
|
KEYWORD(swiftself);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(uwtable);
|
2019-06-27 23:51:40 +08:00
|
|
|
KEYWORD(willreturn);
|
2016-07-04 16:01:29 +08:00
|
|
|
KEYWORD(writeonly);
|
2013-02-06 14:52:58 +08:00
|
|
|
KEYWORD(zeroext);
|
2019-03-13 05:02:54 +08:00
|
|
|
KEYWORD(immarg);
|
IR: Define byref parameter attribute
This allows tracking the in-memory type of a pointer argument to a
function for ABI purposes. This is essentially a stripped down version
of byval to remove some of the stack-copy implications in its
definition.
This includes the base IR changes, and some tests for places where it
should be treated similarly to byval. Codegen support will be in a
future patch.
My original attempt at solving some of these problems was to repurpose
byval with a different address space from the stack. However, it is
technically permitted for the callee to introduce a write to the
argument, although nothing does this in reality. There is also talk of
removing and replacing the byval attribute, so a new attribute would
need to take its place anyway.
This is intended avoid some optimization issues with the current
handling of aggregate arguments, as well as fixes inflexibilty in how
frontends can specify the kernel ABI. The most honest representation
of the amdgpu_kernel convention is to expose all kernel arguments as
loads from constant memory. Today, these are raw, SSA Argument values
and codegen is responsible for turning these into loads.
Background:
There currently isn't a satisfactory way to represent how arguments
for the amdgpu_kernel calling convention are passed. In reality,
arguments are passed in a single, flat, constant memory buffer
implicitly passed to the function. It is also illegal to call this
function in the IR, and this is only ever invoked by a driver of some
kind.
It does not make sense to have a stack passed parameter in this
context as is implied by byval. It is never valid to write to the
kernel arguments, as this would corrupt the inputs seen by other
dispatches of the kernel. These argumets are also not in the same
address space as the stack, so a copy is needed to an alloca. From a
source C-like language, the kernel parameters are invisible.
Semantically, a copy is always required from the constant argument
memory to a mutable variable.
The current clang calling convention lowering emits raw values,
including aggregates into the function argument list, since using
byval would not make sense. This has some unfortunate consequences for
the optimizer. In the aggregate case, we end up with an aggregate
store to alloca, which both SROA and instcombine turn into a store of
each aggregate field. The optimizer never pieces this back together to
see that this is really just a copy from constant memory, so we end up
stuck with expensive stack usage.
This also means the backend dictates the alignment of arguments, and
arbitrarily picks the LLVM IR ABI type alignment. By allowing an
explicit alignment, frontends can make better decisions. For example,
there's real no advantage to an aligment higher than 4, so a frontend
could choose to compact the argument layout. Similarly, there is a
high penalty to using an alignment lower than 4, so a frontend could
opt into more padding for small arguments.
Another design consideration is when it is appropriate to expose the
fact that these arguments are all really passed in adjacent
memory. Currently we have a late IR optimization pass in codegen to
rewrite the kernel argument values into explicit loads to enable
vectorization. In most programs, unrelated argument loads can be
merged together. However, exposing this property directly from the
frontend has some disadvantages. We still need a way to track the
original argument sizes and alignments to report to the driver. I find
using some side-channel, metadata mechanism to track this
unappealing. If the kernel arguments were exposed as a single buffer
to begin with, alias analysis would be unaware that the padding bits
betewen arguments are meaningless. Another family of problems is there
are still some gaps in replacing all of the available parameter
attributes with metadata equivalents once lowered to loads.
The immediate plan is to start using this new attribute to handle all
aggregate argumets for kernels. Long term, it makes sense to migrate
all kernel arguments, including scalars, to be passed indirectly in
the same manner.
Additional context is in D79744.
2020-06-06 04:58:47 +08:00
|
|
|
KEYWORD(byref);
|
2009-01-02 15:01:27 +08:00
|
|
|
|
|
|
|
KEYWORD(type);
|
|
|
|
KEYWORD(opaque);
|
|
|
|
|
2014-06-28 02:19:56 +08:00
|
|
|
KEYWORD(comdat);
|
|
|
|
|
|
|
|
// Comdat types
|
|
|
|
KEYWORD(any);
|
|
|
|
KEYWORD(exactmatch);
|
|
|
|
KEYWORD(largest);
|
|
|
|
KEYWORD(noduplicates);
|
|
|
|
KEYWORD(samesize);
|
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
|
|
|
|
KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);
|
|
|
|
KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole);
|
|
|
|
KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une);
|
2009-01-03 06:46:48 +08:00
|
|
|
|
2011-07-29 05:48:00 +08:00
|
|
|
KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);
|
|
|
|
KEYWORD(umin);
|
|
|
|
|
2019-07-05 20:48:16 +08:00
|
|
|
KEYWORD(vscale);
|
2009-01-02 15:01:27 +08:00
|
|
|
KEYWORD(x);
|
2009-10-28 11:39:23 +08:00
|
|
|
KEYWORD(blockaddress);
|
2011-08-13 04:24:12 +08:00
|
|
|
|
2015-01-09 06:38:29 +08:00
|
|
|
// Metadata types.
|
|
|
|
KEYWORD(distinct);
|
|
|
|
|
2014-08-20 05:30:15 +08:00
|
|
|
// Use-list order directives.
|
|
|
|
KEYWORD(uselistorder);
|
|
|
|
KEYWORD(uselistorder_bb);
|
|
|
|
|
2011-08-13 04:24:12 +08:00
|
|
|
KEYWORD(personality);
|
|
|
|
KEYWORD(cleanup);
|
|
|
|
KEYWORD(catch);
|
|
|
|
KEYWORD(filter);
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2018-06-26 21:56:49 +08:00
|
|
|
// Summary index keywords.
|
|
|
|
KEYWORD(path);
|
|
|
|
KEYWORD(hash);
|
|
|
|
KEYWORD(gv);
|
|
|
|
KEYWORD(guid);
|
|
|
|
KEYWORD(name);
|
|
|
|
KEYWORD(summaries);
|
|
|
|
KEYWORD(flags);
|
2020-05-22 04:28:24 +08:00
|
|
|
KEYWORD(blockcount);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(linkage);
|
|
|
|
KEYWORD(notEligibleToImport);
|
|
|
|
KEYWORD(live);
|
|
|
|
KEYWORD(dsoLocal);
|
[ThinLTO] Auto-hide prevailing linkonce_odr only when all copies eligible
Summary:
We hit undefined references building with ThinLTO when one source file
contained explicit instantiations of a template method (weak_odr) but
there were also implicit instantiations in another file (linkonce_odr),
and the latter was the prevailing copy. In this case the symbol was
marked hidden when the prevailing linkonce_odr copy was promoted to
weak_odr. It led to unsats when the resulting shared library was linked
with other code that contained a reference (expecting to be resolved due
to the explicit instantiation).
Add a CanAutoHide flag to the GV summary to allow the thin link to
identify when all copies are eligible for auto-hiding (because they were
all originally linkonce_odr global unnamed addr), and only do the
auto-hide in that case.
Most of the changes here are due to plumbing the new flag through the
bitcode and llvm assembly, and resulting test changes. I augmented the
existing auto-hide test to check for this situation.
Reviewers: pcc
Subscribers: mehdi_amini, inglorion, eraman, dexonsmith, arphaman, dang, llvm-commits, steven_wu, wmi
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59709
llvm-svn: 360466
2019-05-11 04:08:24 +08:00
|
|
|
KEYWORD(canAutoHide);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(function);
|
|
|
|
KEYWORD(insts);
|
|
|
|
KEYWORD(funcFlags);
|
|
|
|
KEYWORD(readNone);
|
|
|
|
KEYWORD(readOnly);
|
|
|
|
KEYWORD(noRecurse);
|
|
|
|
KEYWORD(returnDoesNotAlias);
|
2018-11-07 03:41:35 +08:00
|
|
|
KEYWORD(noInline);
|
2019-11-09 07:50:55 +08:00
|
|
|
KEYWORD(alwaysInline);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(calls);
|
|
|
|
KEYWORD(callee);
|
2020-06-01 14:49:57 +08:00
|
|
|
KEYWORD(params);
|
|
|
|
KEYWORD(param);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(hotness);
|
|
|
|
KEYWORD(unknown);
|
|
|
|
KEYWORD(hot);
|
|
|
|
KEYWORD(critical);
|
|
|
|
KEYWORD(relbf);
|
|
|
|
KEYWORD(variable);
|
[ThinLTO] Add summary entries for index-based WPD
Summary:
If LTOUnit splitting is disabled, the module summary analysis computes
the summary information necessary to perform single implementation
devirtualization during the thin link with the index and no IR. The
information collected from the regular LTO IR in the current hybrid WPD
algorithm is summarized, including:
1) For vtable definitions, record the function pointers and their offset
within the vtable initializer (subsumes the information collected from
IR by tryFindVirtualCallTargets).
2) A record for each type metadata summarizing the vtable definitions
decorated with that metadata (subsumes the TypeIdentiferMap collected
from IR).
Also added are the necessary bitcode records, and the corresponding
assembly support.
The follow-on index-based WPD patch is D55153.
Depends on D53890.
Reviewers: pcc
Subscribers: mehdi_amini, Prazek, inglorion, eraman, steven_wu, dexonsmith, arphaman, llvm-commits
Differential Revision: https://reviews.llvm.org/D54815
llvm-svn: 364960
2019-07-03 03:38:02 +08:00
|
|
|
KEYWORD(vTableFuncs);
|
|
|
|
KEYWORD(virtFunc);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(aliasee);
|
|
|
|
KEYWORD(refs);
|
|
|
|
KEYWORD(typeIdInfo);
|
|
|
|
KEYWORD(typeTests);
|
|
|
|
KEYWORD(typeTestAssumeVCalls);
|
|
|
|
KEYWORD(typeCheckedLoadVCalls);
|
|
|
|
KEYWORD(typeTestAssumeConstVCalls);
|
|
|
|
KEYWORD(typeCheckedLoadConstVCalls);
|
|
|
|
KEYWORD(vFuncId);
|
|
|
|
KEYWORD(offset);
|
|
|
|
KEYWORD(args);
|
|
|
|
KEYWORD(typeid);
|
[ThinLTO] Add summary entries for index-based WPD
Summary:
If LTOUnit splitting is disabled, the module summary analysis computes
the summary information necessary to perform single implementation
devirtualization during the thin link with the index and no IR. The
information collected from the regular LTO IR in the current hybrid WPD
algorithm is summarized, including:
1) For vtable definitions, record the function pointers and their offset
within the vtable initializer (subsumes the information collected from
IR by tryFindVirtualCallTargets).
2) A record for each type metadata summarizing the vtable definitions
decorated with that metadata (subsumes the TypeIdentiferMap collected
from IR).
Also added are the necessary bitcode records, and the corresponding
assembly support.
The follow-on index-based WPD patch is D55153.
Depends on D53890.
Reviewers: pcc
Subscribers: mehdi_amini, Prazek, inglorion, eraman, steven_wu, dexonsmith, arphaman, llvm-commits
Differential Revision: https://reviews.llvm.org/D54815
llvm-svn: 364960
2019-07-03 03:38:02 +08:00
|
|
|
KEYWORD(typeidCompatibleVTable);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(summary);
|
|
|
|
KEYWORD(typeTestRes);
|
|
|
|
KEYWORD(kind);
|
|
|
|
KEYWORD(unsat);
|
|
|
|
KEYWORD(byteArray);
|
|
|
|
KEYWORD(inline);
|
|
|
|
KEYWORD(single);
|
|
|
|
KEYWORD(allOnes);
|
|
|
|
KEYWORD(sizeM1BitWidth);
|
|
|
|
KEYWORD(alignLog2);
|
|
|
|
KEYWORD(sizeM1);
|
|
|
|
KEYWORD(bitMask);
|
|
|
|
KEYWORD(inlineBits);
|
[ThinLTO] Summarize vcall_visibility metadata
Summary:
Second patch in series to support Safe Whole Program Devirtualization
Enablement, see RFC here:
http://lists.llvm.org/pipermail/llvm-dev/2019-December/137543.html
Summarize vcall_visibility metadata in ThinLTO global variable summary.
Depends on D71907.
Reviewers: pcc, evgeny777, steven_wu
Subscribers: mehdi_amini, Prazek, inglorion, hiraditya, dexonsmith, arphaman, ostannard, llvm-commits, cfe-commits, davidxl
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D71911
2019-12-27 01:31:43 +08:00
|
|
|
KEYWORD(vcall_visibility);
|
2018-06-26 21:56:49 +08:00
|
|
|
KEYWORD(wpdResolutions);
|
|
|
|
KEYWORD(wpdRes);
|
|
|
|
KEYWORD(indir);
|
|
|
|
KEYWORD(singleImpl);
|
|
|
|
KEYWORD(branchFunnel);
|
|
|
|
KEYWORD(singleImplName);
|
|
|
|
KEYWORD(resByArg);
|
|
|
|
KEYWORD(byArg);
|
|
|
|
KEYWORD(uniformRetVal);
|
|
|
|
KEYWORD(uniqueRetVal);
|
|
|
|
KEYWORD(virtualConstProp);
|
|
|
|
KEYWORD(info);
|
|
|
|
KEYWORD(byte);
|
|
|
|
KEYWORD(bit);
|
2018-11-23 18:54:51 +08:00
|
|
|
KEYWORD(varFlags);
|
2018-06-26 21:56:49 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
#undef KEYWORD
|
|
|
|
|
|
|
|
// Keywords for types.
|
2015-02-21 07:49:24 +08:00
|
|
|
#define TYPEKEYWORD(STR, LLVMTY) \
|
|
|
|
do { \
|
2015-02-21 08:18:40 +08:00
|
|
|
if (Keyword == STR) { \
|
2015-02-21 07:49:24 +08:00
|
|
|
TyVal = LLVMTY; \
|
|
|
|
return lltok::Type; \
|
|
|
|
} \
|
|
|
|
} while (false)
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2009-08-14 05:58:54 +08:00
|
|
|
TYPEKEYWORD("void", Type::getVoidTy(Context));
|
2011-12-17 08:04:22 +08:00
|
|
|
TYPEKEYWORD("half", Type::getHalfTy(Context));
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 06:49:38 +08:00
|
|
|
TYPEKEYWORD("bfloat", Type::getBFloatTy(Context));
|
2009-08-14 05:58:54 +08:00
|
|
|
TYPEKEYWORD("float", Type::getFloatTy(Context));
|
|
|
|
TYPEKEYWORD("double", Type::getDoubleTy(Context));
|
|
|
|
TYPEKEYWORD("x86_fp80", Type::getX86_FP80Ty(Context));
|
|
|
|
TYPEKEYWORD("fp128", Type::getFP128Ty(Context));
|
|
|
|
TYPEKEYWORD("ppc_fp128", Type::getPPC_FP128Ty(Context));
|
|
|
|
TYPEKEYWORD("label", Type::getLabelTy(Context));
|
|
|
|
TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
|
2010-09-11 04:55:01 +08:00
|
|
|
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
|
2015-08-14 13:09:07 +08:00
|
|
|
TYPEKEYWORD("token", Type::getTokenTy(Context));
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
#undef TYPEKEYWORD
|
|
|
|
|
|
|
|
// Keywords for instructions.
|
2015-02-21 07:49:24 +08:00
|
|
|
#define INSTKEYWORD(STR, Enum) \
|
|
|
|
do { \
|
2015-02-21 08:18:40 +08:00
|
|
|
if (Keyword == #STR) { \
|
2015-02-21 07:49:24 +08:00
|
|
|
UIntVal = Instruction::Enum; \
|
|
|
|
return lltok::kw_##STR; \
|
|
|
|
} \
|
|
|
|
} while (false)
|
2009-01-02 15:01:27 +08:00
|
|
|
|
2018-11-14 02:15:47 +08:00
|
|
|
INSTKEYWORD(fneg, FNeg);
|
|
|
|
|
2009-06-05 06:49:04 +08:00
|
|
|
INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);
|
|
|
|
INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);
|
|
|
|
INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);
|
2009-01-02 15:01:27 +08:00
|
|
|
INSTKEYWORD(udiv, UDiv); INSTKEYWORD(sdiv, SDiv); INSTKEYWORD(fdiv, FDiv);
|
|
|
|
INSTKEYWORD(urem, URem); INSTKEYWORD(srem, SRem); INSTKEYWORD(frem, FRem);
|
|
|
|
INSTKEYWORD(shl, Shl); INSTKEYWORD(lshr, LShr); INSTKEYWORD(ashr, AShr);
|
|
|
|
INSTKEYWORD(and, And); INSTKEYWORD(or, Or); INSTKEYWORD(xor, Xor);
|
|
|
|
INSTKEYWORD(icmp, ICmp); INSTKEYWORD(fcmp, FCmp);
|
|
|
|
|
|
|
|
INSTKEYWORD(phi, PHI);
|
|
|
|
INSTKEYWORD(call, Call);
|
|
|
|
INSTKEYWORD(trunc, Trunc);
|
|
|
|
INSTKEYWORD(zext, ZExt);
|
|
|
|
INSTKEYWORD(sext, SExt);
|
|
|
|
INSTKEYWORD(fptrunc, FPTrunc);
|
|
|
|
INSTKEYWORD(fpext, FPExt);
|
|
|
|
INSTKEYWORD(uitofp, UIToFP);
|
|
|
|
INSTKEYWORD(sitofp, SIToFP);
|
|
|
|
INSTKEYWORD(fptoui, FPToUI);
|
|
|
|
INSTKEYWORD(fptosi, FPToSI);
|
|
|
|
INSTKEYWORD(inttoptr, IntToPtr);
|
|
|
|
INSTKEYWORD(ptrtoint, PtrToInt);
|
|
|
|
INSTKEYWORD(bitcast, BitCast);
|
2013-11-15 09:34:59 +08:00
|
|
|
INSTKEYWORD(addrspacecast, AddrSpaceCast);
|
2009-01-02 15:01:27 +08:00
|
|
|
INSTKEYWORD(select, Select);
|
|
|
|
INSTKEYWORD(va_arg, VAArg);
|
|
|
|
INSTKEYWORD(ret, Ret);
|
|
|
|
INSTKEYWORD(br, Br);
|
|
|
|
INSTKEYWORD(switch, Switch);
|
2009-10-28 08:19:10 +08:00
|
|
|
INSTKEYWORD(indirectbr, IndirectBr);
|
2009-01-02 15:01:27 +08:00
|
|
|
INSTKEYWORD(invoke, Invoke);
|
2011-07-31 14:30:59 +08:00
|
|
|
INSTKEYWORD(resume, Resume);
|
2009-01-02 15:01:27 +08:00
|
|
|
INSTKEYWORD(unreachable, Unreachable);
|
2019-02-09 04:48:56 +08:00
|
|
|
INSTKEYWORD(callbr, CallBr);
|
2009-01-02 15:01:27 +08:00
|
|
|
|
|
|
|
INSTKEYWORD(alloca, Alloca);
|
|
|
|
INSTKEYWORD(load, Load);
|
|
|
|
INSTKEYWORD(store, Store);
|
2011-07-29 05:48:00 +08:00
|
|
|
INSTKEYWORD(cmpxchg, AtomicCmpXchg);
|
|
|
|
INSTKEYWORD(atomicrmw, AtomicRMW);
|
2011-07-26 07:16:38 +08:00
|
|
|
INSTKEYWORD(fence, Fence);
|
2009-01-02 15:01:27 +08:00
|
|
|
INSTKEYWORD(getelementptr, GetElementPtr);
|
|
|
|
|
|
|
|
INSTKEYWORD(extractelement, ExtractElement);
|
|
|
|
INSTKEYWORD(insertelement, InsertElement);
|
|
|
|
INSTKEYWORD(shufflevector, ShuffleVector);
|
|
|
|
INSTKEYWORD(extractvalue, ExtractValue);
|
|
|
|
INSTKEYWORD(insertvalue, InsertValue);
|
2011-08-13 04:24:12 +08:00
|
|
|
INSTKEYWORD(landingpad, LandingPad);
|
2015-08-01 01:58:14 +08:00
|
|
|
INSTKEYWORD(cleanupret, CleanupRet);
|
|
|
|
INSTKEYWORD(catchret, CatchRet);
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
INSTKEYWORD(catchswitch, CatchSwitch);
|
2015-08-01 01:58:14 +08:00
|
|
|
INSTKEYWORD(catchpad, CatchPad);
|
|
|
|
INSTKEYWORD(cleanuppad, CleanupPad);
|
2016-08-19 01:56:27 +08:00
|
|
|
|
[IR] Redefine Freeze instruction
Summary:
This patch redefines freeze instruction from being UnaryOperator to a subclass of UnaryInstruction.
ConstantExpr freeze is removed, as discussed in the previous review.
FreezeOperator is not added because there's no ConstantExpr freeze.
`freeze i8* null` test is added to `test/Bindings/llvm-c/freeze.ll` as well, because the null pointer-related bug in `tools/llvm-c/echo.cpp` is now fixed.
InstVisitor has visitFreeze now because freeze is not unaryop anymore.
Reviewers: whitequark, deadalnix, craig.topper, jdoerfert, lebedev.ri
Reviewed By: craig.topper, lebedev.ri
Subscribers: regehr, nlopes, mehdi_amini, hiraditya, steven_wu, dexonsmith, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69932
2019-11-07 00:17:49 +08:00
|
|
|
INSTKEYWORD(freeze, Freeze);
|
|
|
|
|
2007-12-16 17:16:12 +08:00
|
|
|
#undef INSTKEYWORD
|
|
|
|
|
2015-02-13 09:17:35 +08:00
|
|
|
#define DWKEYWORD(TYPE, TOKEN) \
|
2015-02-21 07:49:24 +08:00
|
|
|
do { \
|
2015-02-21 08:18:40 +08:00
|
|
|
if (Keyword.startswith("DW_" #TYPE "_")) { \
|
|
|
|
StrVal.assign(Keyword.begin(), Keyword.end()); \
|
2015-02-21 07:49:24 +08:00
|
|
|
return lltok::TOKEN; \
|
|
|
|
} \
|
|
|
|
} while (false)
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2015-02-13 09:17:35 +08:00
|
|
|
DWKEYWORD(TAG, DwarfTag);
|
|
|
|
DWKEYWORD(ATE, DwarfAttEncoding);
|
2015-02-13 09:28:16 +08:00
|
|
|
DWKEYWORD(VIRTUALITY, DwarfVirtuality);
|
2015-02-13 09:21:25 +08:00
|
|
|
DWKEYWORD(LANG, DwarfLang);
|
2016-06-09 04:34:29 +08:00
|
|
|
DWKEYWORD(CC, DwarfCC);
|
2015-02-13 09:42:09 +08:00
|
|
|
DWKEYWORD(OP, DwarfOp);
|
2015-12-10 20:56:35 +08:00
|
|
|
DWKEYWORD(MACINFO, DwarfMacinfo);
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2015-02-13 09:17:35 +08:00
|
|
|
#undef DWKEYWORD
|
2016-08-19 01:56:27 +08:00
|
|
|
|
2015-02-21 09:02:18 +08:00
|
|
|
if (Keyword.startswith("DIFlag")) {
|
|
|
|
StrVal.assign(Keyword.begin(), Keyword.end());
|
|
|
|
return lltok::DIFlag;
|
|
|
|
}
|
2016-12-25 18:12:09 +08:00
|
|
|
|
2018-11-29 05:14:32 +08:00
|
|
|
if (Keyword.startswith("DISPFlag")) {
|
|
|
|
StrVal.assign(Keyword.begin(), Keyword.end());
|
|
|
|
return lltok::DISPFlag;
|
|
|
|
}
|
|
|
|
|
2016-12-25 18:12:09 +08:00
|
|
|
if (Keyword.startswith("CSK_")) {
|
|
|
|
StrVal.assign(Keyword.begin(), Keyword.end());
|
|
|
|
return lltok::ChecksumKind;
|
|
|
|
}
|
|
|
|
|
2016-04-01 07:56:58 +08:00
|
|
|
if (Keyword == "NoDebug" || Keyword == "FullDebug" ||
|
2018-08-02 03:38:20 +08:00
|
|
|
Keyword == "LineTablesOnly" || Keyword == "DebugDirectivesOnly") {
|
2016-04-01 07:56:58 +08:00
|
|
|
StrVal.assign(Keyword.begin(), Keyword.end());
|
|
|
|
return lltok::EmissionKind;
|
|
|
|
}
|
2015-02-21 09:02:18 +08:00
|
|
|
|
2018-08-17 05:29:55 +08:00
|
|
|
if (Keyword == "GNU" || Keyword == "None" || Keyword == "Default") {
|
|
|
|
StrVal.assign(Keyword.begin(), Keyword.end());
|
|
|
|
return lltok::NameTableKind;
|
|
|
|
}
|
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
|
|
|
|
// the CFE to avoid forcing it to deal with 64-bit numbers.
|
|
|
|
if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
|
2013-02-13 05:21:59 +08:00
|
|
|
TokStart[1] == '0' && TokStart[2] == 'x' &&
|
|
|
|
isxdigit(static_cast<unsigned char>(TokStart[3]))) {
|
2007-11-18 16:46:26 +08:00
|
|
|
int len = CurPtr-TokStart-3;
|
|
|
|
uint32_t bits = len * 4;
|
2014-12-10 07:50:38 +08:00
|
|
|
StringRef HexStr(TokStart + 3, len);
|
2016-08-12 05:15:00 +08:00
|
|
|
if (!all_of(HexStr, isxdigit)) {
|
2014-12-10 07:50:38 +08:00
|
|
|
// Bad token, return it as an error.
|
|
|
|
CurPtr = TokStart+3;
|
|
|
|
return lltok::Error;
|
|
|
|
}
|
|
|
|
APInt Tmp(bits, HexStr, 16);
|
2007-11-18 16:46:26 +08:00
|
|
|
uint32_t activeBits = Tmp.getActiveBits();
|
|
|
|
if (activeBits > 0 && activeBits < bits)
|
2010-12-07 16:25:19 +08:00
|
|
|
Tmp = Tmp.trunc(activeBits);
|
2009-01-02 15:01:27 +08:00
|
|
|
APSIntVal = APSInt(Tmp, TokStart[0] == 'u');
|
|
|
|
return lltok::APSInt;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-19 02:43:24 +08:00
|
|
|
// If this is "cc1234", return this as just "cc".
|
2007-11-18 16:46:26 +08:00
|
|
|
if (TokStart[0] == 'c' && TokStart[1] == 'c') {
|
|
|
|
CurPtr = TokStart+2;
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::kw_cc;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
// Finally, if this isn't known, return an error.
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr = TokStart+1;
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::Error;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex all tokens that start with a 0x prefix, knowing they match and are not
|
|
|
|
/// labels.
|
2007-11-18 16:46:26 +08:00
|
|
|
/// HexFPConstant 0x[0-9A-Fa-f]+
|
|
|
|
/// HexFP80Constant 0xK[0-9A-Fa-f]+
|
|
|
|
/// HexFP128Constant 0xL[0-9A-Fa-f]+
|
|
|
|
/// HexPPC128Constant 0xM[0-9A-Fa-f]+
|
2012-05-24 23:59:06 +08:00
|
|
|
/// HexHalfConstant 0xH[0-9A-Fa-f]+
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 06:49:38 +08:00
|
|
|
/// HexBFloatConstant 0xR[0-9A-Fa-f]+
|
2009-01-02 15:01:27 +08:00
|
|
|
lltok::Kind LLLexer::Lex0x() {
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr = TokStart + 2;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
char Kind;
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 06:49:38 +08:00
|
|
|
if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H' ||
|
|
|
|
CurPtr[0] == 'R') {
|
2007-11-18 16:46:26 +08:00
|
|
|
Kind = *CurPtr++;
|
|
|
|
} else {
|
|
|
|
Kind = 'J';
|
|
|
|
}
|
|
|
|
|
2013-02-13 05:21:59 +08:00
|
|
|
if (!isxdigit(static_cast<unsigned char>(CurPtr[0]))) {
|
2009-01-02 15:01:27 +08:00
|
|
|
// Bad token, return it as an error.
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr = TokStart+1;
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::Error;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isxdigit(static_cast<unsigned char>(CurPtr[0])))
|
2007-11-18 16:46:26 +08:00
|
|
|
++CurPtr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
if (Kind == 'J') {
|
|
|
|
// HexFPConstant - Floating point constant represented in IEEE format as a
|
|
|
|
// hexadecimal number for when exponential notation is not precise enough.
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 06:49:38 +08:00
|
|
|
// Half, BFloat, Float, and double only.
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::IEEEdouble(),
|
2016-08-05 19:59:49 +08:00
|
|
|
APInt(64, HexIntToVal(TokStart + 2, CurPtr)));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APFloat;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
uint64_t Pair[2];
|
|
|
|
switch (Kind) {
|
2009-07-15 00:55:14 +08:00
|
|
|
default: llvm_unreachable("Unknown kind!");
|
2007-11-18 16:46:26 +08:00
|
|
|
case 'K':
|
|
|
|
// F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
|
2009-03-24 05:16:53 +08:00
|
|
|
FP80HexToIntPair(TokStart+3, CurPtr, Pair);
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::x87DoubleExtended(), APInt(80, Pair));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APFloat;
|
2007-11-18 16:46:26 +08:00
|
|
|
case 'L':
|
|
|
|
// F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
|
2009-03-24 05:16:53 +08:00
|
|
|
HexToIntPair(TokStart+3, CurPtr, Pair);
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::IEEEquad(), APInt(128, Pair));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APFloat;
|
2007-11-18 16:46:26 +08:00
|
|
|
case 'M':
|
|
|
|
// PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
|
2009-03-24 05:16:53 +08:00
|
|
|
HexToIntPair(TokStart+3, CurPtr, Pair);
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::PPCDoubleDouble(), APInt(128, Pair));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APFloat;
|
2012-05-24 23:59:06 +08:00
|
|
|
case 'H':
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::IEEEhalf(),
|
2013-01-22 17:46:31 +08:00
|
|
|
APInt(16,HexIntToVal(TokStart+3, CurPtr)));
|
2012-05-24 23:59:06 +08:00
|
|
|
return lltok::APFloat;
|
[IR][BFloat] Add BFloat IR type
Summary:
The BFloat IR type is introduced to provide support for, initially, the BFloat16
datatype introduced with the Armv8.6 architecture (optional from Armv8.2
onwards). It has an 8-bit exponent and a 7-bit mantissa and behaves like an IEEE
754 floating point IR type.
This is part of a patch series upstreaming Armv8.6 features. Subsequent patches
will upstream intrinsics support and C-lang support for BFloat.
Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, sdesmalen, deadalnix, ctetreau
Subscribers: hiraditya, llvm-commits, danielkiss, arphaman, kristof.beyls, dexonsmith
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D78190
2020-04-01 06:49:38 +08:00
|
|
|
case 'R':
|
|
|
|
// Brain floating point
|
|
|
|
APFloatVal = APFloat(APFloat::BFloat(),
|
|
|
|
APInt(16, HexIntToVal(TokStart + 3, CurPtr)));
|
|
|
|
return lltok::APFloat;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex tokens for a label or a numeric constant, possibly starting with -.
|
2007-11-18 16:46:26 +08:00
|
|
|
/// Label [-a-zA-Z$._0-9]+:
|
|
|
|
/// NInteger -[0-9]+
|
|
|
|
/// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
|
|
|
|
/// PInteger [0-9]+
|
|
|
|
/// HexFPConstant 0x[0-9A-Fa-f]+
|
|
|
|
/// HexFP80Constant 0xK[0-9A-Fa-f]+
|
|
|
|
/// HexFP128Constant 0xL[0-9A-Fa-f]+
|
|
|
|
/// HexPPC128Constant 0xM[0-9A-Fa-f]+
|
2009-01-02 15:01:27 +08:00
|
|
|
lltok::Kind LLLexer::LexDigitOrNegative() {
|
2012-11-16 14:10:48 +08:00
|
|
|
// If the letter after the negative is not a number, this is probably a label.
|
2013-02-13 05:21:59 +08:00
|
|
|
if (!isdigit(static_cast<unsigned char>(TokStart[0])) &&
|
|
|
|
!isdigit(static_cast<unsigned char>(CurPtr[0]))) {
|
2007-11-18 16:46:26 +08:00
|
|
|
// Okay, this is not a number after the -, it's probably a label.
|
|
|
|
if (const char *End = isLabelTail(CurPtr)) {
|
2009-01-02 15:01:27 +08:00
|
|
|
StrVal.assign(TokStart, End-1);
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr = End;
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::LabelStr;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::Error;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// At this point, it is either a label, int or fp constant.
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Skip digits, we have at least one.
|
2013-02-13 05:21:59 +08:00
|
|
|
for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
|
2007-12-16 17:16:12 +08:00
|
|
|
/*empty*/;
|
|
|
|
|
IR: Support parsing numeric block ids, and emit them in textual output.
Just as as llvm IR supports explicitly specifying numeric value ids
for instructions, and emits them by default in textual output, now do
the same for blocks.
This is a slightly incompatible change in the textual IR format.
Previously, llvm would parse numeric labels as string names. E.g.
define void @f() {
br label %"55"
55:
ret void
}
defined a label *named* "55", even without needing to be quoted, while
the reference required quoting. Now, if you intend a block label which
looks like a value number to be a name, you must quote it in the
definition too (e.g. `"55":`).
Previously, llvm would print nameless blocks only as a comment, and
would omit it if there was no predecessor. This could cause confusion
for readers of the IR, just as unnamed instructions did prior to the
addition of "%5 = " syntax, back in 2008 (PR2480).
Now, it will always print a label for an unnamed block, with the
exception of the entry block. (IMO it may be better to print it for
the entry-block as well. However, that requires updating many more
tests.)
Thus, the following is supported, and is the canonical printing:
define i32 @f(i32, i32) {
%3 = add i32 %0, %1
br label %4
4:
ret i32 %3
}
New test cases covering this behavior are added, and other tests
updated as required.
Differential Revision: https://reviews.llvm.org/D58548
llvm-svn: 356789
2019-03-23 02:27:13 +08:00
|
|
|
// Check if this is a fully-numeric label:
|
|
|
|
if (isdigit(TokStart[0]) && CurPtr[0] == ':') {
|
|
|
|
uint64_t Val = atoull(TokStart, CurPtr);
|
|
|
|
++CurPtr; // Skip the colon.
|
|
|
|
if ((unsigned)Val != Val)
|
|
|
|
Error("invalid value number (too large)!");
|
|
|
|
UIntVal = unsigned(Val);
|
|
|
|
return lltok::LabelID;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check to see if this really is a string label, e.g. "-1:".
|
2007-11-18 16:46:26 +08:00
|
|
|
if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {
|
|
|
|
if (const char *End = isLabelTail(CurPtr)) {
|
2009-01-02 15:01:27 +08:00
|
|
|
StrVal.assign(TokStart, End-1);
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr = End;
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::LabelStr;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// If the next character is a '.', then it is a fp value, otherwise its
|
|
|
|
// integer.
|
|
|
|
if (CurPtr[0] != '.') {
|
|
|
|
if (TokStart[0] == '0' && TokStart[1] == 'x')
|
|
|
|
return Lex0x();
|
2015-06-24 02:22:10 +08:00
|
|
|
APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APSInt;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
++CurPtr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Skip over [0-9]*([eE][-+]?[0-9]+)?
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
|
2013-02-13 05:21:59 +08:00
|
|
|
if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
|
|
|
|
((CurPtr[1] == '-' || CurPtr[1] == '+') &&
|
|
|
|
isdigit(static_cast<unsigned char>(CurPtr[2])))) {
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr += 2;
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::IEEEdouble(),
|
2016-06-03 04:04:44 +08:00
|
|
|
StringRef(TokStart, CurPtr - TokStart));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APFloat;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
|
2015-06-07 14:40:24 +08:00
|
|
|
/// Lex a floating point constant starting with +.
|
2007-11-18 16:46:26 +08:00
|
|
|
/// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
|
2009-01-02 15:01:27 +08:00
|
|
|
lltok::Kind LLLexer::LexPositive() {
|
2007-11-18 16:46:26 +08:00
|
|
|
// If the letter after the negative is a number, this is probably not a
|
|
|
|
// label.
|
2013-02-13 05:21:59 +08:00
|
|
|
if (!isdigit(static_cast<unsigned char>(CurPtr[0])))
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::Error;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Skip digits.
|
2013-02-13 05:21:59 +08:00
|
|
|
for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
|
2007-12-16 17:16:12 +08:00
|
|
|
/*empty*/;
|
2007-11-18 16:46:26 +08:00
|
|
|
|
|
|
|
// At this point, we need a '.'.
|
|
|
|
if (CurPtr[0] != '.') {
|
|
|
|
CurPtr = TokStart+1;
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::Error;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
++CurPtr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
// Skip over [0-9]*([eE][-+]?[0-9]+)?
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2007-11-18 16:46:26 +08:00
|
|
|
if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
|
2013-02-13 05:21:59 +08:00
|
|
|
if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
|
|
|
|
((CurPtr[1] == '-' || CurPtr[1] == '+') &&
|
|
|
|
isdigit(static_cast<unsigned char>(CurPtr[2])))) {
|
2007-11-18 16:46:26 +08:00
|
|
|
CurPtr += 2;
|
2013-02-13 05:21:59 +08:00
|
|
|
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|
|
|
|
}
|
2007-12-16 17:16:12 +08:00
|
|
|
|
2016-12-14 19:57:17 +08:00
|
|
|
APFloatVal = APFloat(APFloat::IEEEdouble(),
|
2016-06-03 04:04:44 +08:00
|
|
|
StringRef(TokStart, CurPtr - TokStart));
|
2009-01-02 15:01:27 +08:00
|
|
|
return lltok::APFloat;
|
2007-11-18 16:46:26 +08:00
|
|
|
}
|