Choose type for integer literals to match the target mask size (if possible).

On a target with a 16-bit mask (for example), we would choose the type
of an integer literal "1024" to be an int16.  Previously, we used an int32,
which is a worse fit and leads to less efficient code than an int16
on a 16-bit mask target.  (However, we'd still give an integer literal
1000000 the type int32, even in a 16-bit target.)

Updated the tests to still pass with 8 and 16-bit targets, given this
change.
This commit is contained in:
Matt Pharr
2013-07-23 17:01:03 -07:00
parent 9ba49eabb2
commit f7f281a256
61 changed files with 166 additions and 120 deletions

27
lex.ll
View File

@@ -77,6 +77,8 @@ static int allTokens[] = {
TOKEN_UNSIGNED, TOKEN_VARYING, TOKEN_VOID, TOKEN_WHILE,
TOKEN_STRING_C_LITERAL, TOKEN_DOTDOTDOT,
TOKEN_FLOAT_CONSTANT,
TOKEN_INT8_CONSTANT, TOKEN_UINT8_CONSTANT,
TOKEN_INT16_CONSTANT, TOKEN_UINT16_CONSTANT,
TOKEN_INT32_CONSTANT, TOKEN_UINT32_CONSTANT,
TOKEN_INT64_CONSTANT, TOKEN_UINT64_CONSTANT,
TOKEN_INC_OP, TOKEN_DEC_OP, TOKEN_LEFT_OP, TOKEN_RIGHT_OP, TOKEN_LE_OP,
@@ -150,6 +152,10 @@ void ParserInit() {
tokenToName[TOKEN_STRING_C_LITERAL] = "\"C\"";
tokenToName[TOKEN_DOTDOTDOT] = "...";
tokenToName[TOKEN_FLOAT_CONSTANT] = "TOKEN_FLOAT_CONSTANT";
tokenToName[TOKEN_INT8_CONSTANT] = "TOKEN_INT8_CONSTANT";
tokenToName[TOKEN_UINT8_CONSTANT] = "TOKEN_UINT8_CONSTANT";
tokenToName[TOKEN_INT16_CONSTANT] = "TOKEN_INT16_CONSTANT";
tokenToName[TOKEN_UINT16_CONSTANT] = "TOKEN_UINT16_CONSTANT";
tokenToName[TOKEN_INT32_CONSTANT] = "TOKEN_INT32_CONSTANT";
tokenToName[TOKEN_UINT32_CONSTANT] = "TOKEN_UINT32_CONSTANT";
tokenToName[TOKEN_INT64_CONSTANT] = "TOKEN_INT64_CONSTANT";
@@ -260,6 +266,10 @@ void ParserInit() {
tokenNameRemap["TOKEN_STRING_C_LITERAL"] = "\"C\"";
tokenNameRemap["TOKEN_DOTDOTDOT"] = "\'...\'";
tokenNameRemap["TOKEN_FLOAT_CONSTANT"] = "float constant";
tokenNameRemap["TOKEN_INT8_CONSTANT"] = "int8 constant";
tokenNameRemap["TOKEN_UINT8_CONSTANT"] = "unsigned int8 constant";
tokenNameRemap["TOKEN_INT16_CONSTANT"] = "int16 constant";
tokenNameRemap["TOKEN_UINT16_CONSTANT"] = "unsigned int16 constant";
tokenNameRemap["TOKEN_INT32_CONSTANT"] = "int32 constant";
tokenNameRemap["TOKEN_UINT32_CONSTANT"] = "unsigned int32 constant";
tokenNameRemap["TOKEN_INT64_CONSTANT"] = "int64 constant";
@@ -599,7 +609,22 @@ lParseInteger(bool dotdotdot) {
}
else {
// No u or l suffix
// First, see if we can fit this into a 32-bit integer...
// If we're compiling to an 8-bit mask target and the constant
// fits into 8 bits, return an 8-bit int.
if (g->target->getMaskBitCount() == 8) {
if (yylval.intVal <= 0x7fULL)
return TOKEN_INT8_CONSTANT;
else if (yylval.intVal <= 0xffULL)
return TOKEN_UINT8_CONSTANT;
}
// And similarly for 16-bit masks and constants
if (g->target->getMaskBitCount() == 16) {
if (yylval.intVal <= 0x7fffULL)
return TOKEN_INT16_CONSTANT;
else if (yylval.intVal <= 0xffffULL)
return TOKEN_UINT16_CONSTANT;
}
// Otherwise, see if we can fit this into a 32-bit integer...
if (yylval.intVal <= 0x7fffffffULL)
return TOKEN_INT32_CONSTANT;
else if (yylval.intVal <= 0xffffffffULL)