Add syntax for cold blocks to CLIF.
This commit adds support for denoting cold blocks in the CLIF text
format as follows:
```plain
function %f() {
block0(...):
...
block1 cold:
...
block2(...) cold:
...
block3:
...
```
With this syntax, we are able to see the cold-block flag in CLIF, we can
write tests using it, and it is preserved when round-tripping.
Fixes #3701.
This commit is contained in:
@@ -447,6 +447,11 @@ impl Context {
|
||||
self.function.layout.append_block(block);
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
/// Set a block as cold.
|
||||
fn set_cold_block(&mut self, block: Block) {
|
||||
self.function.layout.set_cold(block);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
@@ -1856,7 +1861,8 @@ impl<'a> Parser<'a> {
|
||||
// Parse a basic block, add contents to `ctx`.
|
||||
//
|
||||
// extended-basic-block ::= * block-header { instruction }
|
||||
// block-header ::= Block(block) [block-params] ":"
|
||||
// block-header ::= Block(block) [block-params] [block-flags] ":"
|
||||
// block-flags ::= [Cold]
|
||||
//
|
||||
fn parse_basic_block(&mut self, ctx: &mut Context) -> ParseResult<()> {
|
||||
// Collect comments for the next block.
|
||||
@@ -1869,12 +1875,16 @@ impl<'a> Parser<'a> {
|
||||
return Err(self.error("too many blocks"));
|
||||
}
|
||||
|
||||
if !self.optional(Token::Colon) {
|
||||
// block-header ::= Block(block) [ * block-params ] ":"
|
||||
if self.token() == Some(Token::LPar) {
|
||||
self.parse_block_params(ctx, block)?;
|
||||
self.match_token(Token::Colon, "expected ':' after block parameters")?;
|
||||
}
|
||||
|
||||
if self.optional(Token::Cold) {
|
||||
ctx.set_cold_block(block);
|
||||
}
|
||||
|
||||
self.match_token(Token::Colon, "expected ':' after block parameters")?;
|
||||
|
||||
// Collect any trailing comments.
|
||||
self.token();
|
||||
self.claim_gathered_comments(block);
|
||||
@@ -3728,4 +3738,23 @@ mod tests {
|
||||
"0x00000003000000020000000100000000"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_cold_blocks() {
|
||||
let code = "function %test() {
|
||||
block0 cold:
|
||||
return
|
||||
block1(v0: i32) cold:
|
||||
return
|
||||
block2(v1: i32):
|
||||
return
|
||||
}";
|
||||
|
||||
let mut parser = Parser::new(code);
|
||||
let func = parser.parse_function().unwrap().0;
|
||||
assert_eq!(func.layout.blocks().count(), 3);
|
||||
assert!(func.layout.is_cold(Block::from_u32(0)));
|
||||
assert!(func.layout.is_cold(Block::from_u32(1)));
|
||||
assert!(!func.layout.is_cold(Block::from_u32(2)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user