MIR Serialization: Serialize the external symbol machine operands.
authorAlex Lorenz <arphaman@gmail.com>
Tue, 21 Jul 2015 16:59:53 +0000 (16:59 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Tue, 21 Jul 2015 16:59:53 +0000 (16:59 +0000)
Reviewers: Duncan P. N. Exon Smith

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242806 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineFunction.h
lib/CodeGen/MIRParser/MILexer.cpp
lib/CodeGen/MIRParser/MILexer.h
lib/CodeGen/MIRParser/MIParser.cpp
lib/CodeGen/MIRPrinter.cpp
lib/CodeGen/MachineFunction.cpp
test/CodeGen/MIR/X86/external-symbol-operands.mir [new file with mode: 0644]

index c15ee1c006cda12c73aa59bb221c44769084a2c4..6297defb1c5c4b840b3ebb343eb5742f21b5ad7c 100644 (file)
@@ -475,6 +475,9 @@ public:
     extractStoreMemRefs(MachineInstr::mmo_iterator Begin,
                         MachineInstr::mmo_iterator End);
 
+  /// Allocate a string and populate it with the given external symbol name.
+  const char *createExternalSymbolName(StringRef Name);
+
   //===--------------------------------------------------------------------===//
   // Label Manipulation.
   //
index ee4d59ddcaaff1bfef7672e72293b4c1c53885f8..2a1caab57941d3430002aacb7bc124d2cb2f77d0 100644 (file)
@@ -271,6 +271,36 @@ static Cursor maybeLexGlobalValue(
   return C;
 }
 
+static Cursor lexName(
+    Cursor C, MIToken &Token, MIToken::TokenKind Type,
+    MIToken::TokenKind QuotedType, unsigned PrefixLength,
+    function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
+  auto Range = C;
+  C.advance(PrefixLength);
+  if (C.peek() == '"') {
+    if (Cursor R = lexStringConstant(C, ErrorCallback)) {
+      Token = MIToken(QuotedType, Range.upto(R), PrefixLength);
+      return R;
+    }
+    Token = MIToken(MIToken::Error, Range.remaining());
+    return Range;
+  }
+  while (isIdentifierChar(C.peek()))
+    C.advance();
+  Token = MIToken(Type, Range.upto(C), PrefixLength);
+  return C;
+}
+
+static Cursor maybeLexExternalSymbol(
+    Cursor C, MIToken &Token,
+    function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
+  if (C.peek() != '$')
+    return None;
+  return lexName(C, Token, MIToken::ExternalSymbol,
+                 MIToken::QuotedExternalSymbol,
+                 /*PrefixLength=*/1, ErrorCallback);
+}
+
 static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) {
   if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1))))
     return None;
@@ -331,6 +361,8 @@ StringRef llvm::lexMIToken(
     return R.remaining();
   if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
     return R.remaining();
+  if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback))
+    return R.remaining();
   if (Cursor R = maybeLexIntegerLiteral(C, Token))
     return R.remaining();
   if (Cursor R = maybeLexSymbol(C, Token))
index fd94d61cab3e10a1760925c596dfc2a51edc0cd4..7f36b9ab7f6288968421fbb3c640c5f04993bd28 100644 (file)
@@ -54,6 +54,8 @@ struct MIToken {
     NamedGlobalValue,
     QuotedNamedGlobalValue,
     GlobalValue,
+    ExternalSymbol,
+    QuotedExternalSymbol,
 
     // Other tokens
     IntegerLiteral,
@@ -96,7 +98,9 @@ public:
 
   StringRef::iterator location() const { return Range.begin(); }
 
-  bool isStringValueQuoted() const { return Kind == QuotedNamedGlobalValue; }
+  bool isStringValueQuoted() const {
+    return Kind == QuotedNamedGlobalValue || Kind == QuotedExternalSymbol;
+  }
 
   /// Return the token's raw string value.
   ///
index 34d3e1e3c53a36983361c253dbd4c2606b834592..ca98ae3c97f6aad55f4737ee32a4e8d5dc4bcb1c 100644 (file)
@@ -110,6 +110,7 @@ public:
   bool parseGlobalAddressOperand(MachineOperand &Dest);
   bool parseConstantPoolIndexOperand(MachineOperand &Dest);
   bool parseJumpTableIndexOperand(MachineOperand &Dest);
+  bool parseExternalSymbolOperand(MachineOperand &Dest);
   bool parseMachineOperand(MachineOperand &Dest);
 
 private:
@@ -560,6 +561,17 @@ bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
   return false;
 }
 
+bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
+  assert(Token.is(MIToken::ExternalSymbol) ||
+         Token.is(MIToken::QuotedExternalSymbol));
+  StringValueUtility Name(Token);
+  const char *Symbol = MF.createExternalSymbolName(Name);
+  lex();
+  // TODO: Parse the target flags.
+  Dest = MachineOperand::CreateES(Symbol);
+  return false;
+}
+
 bool MIParser::parseMachineOperand(MachineOperand &Dest) {
   switch (Token.kind()) {
   case MIToken::kw_implicit:
@@ -587,6 +599,9 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
     return parseConstantPoolIndexOperand(Dest);
   case MIToken::JumpTableIndex:
     return parseJumpTableIndexOperand(Dest);
+  case MIToken::ExternalSymbol:
+  case MIToken::QuotedExternalSymbol:
+    return parseExternalSymbolOperand(Dest);
   case MIToken::Error:
     return true;
   case MIToken::Identifier:
index c3a655aec0b4203b4bc83a71a7c8cc6436792802..9413a7e381187fa1ed2b469bbc2ef185cc7d09b5 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MIRYamlMapping.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ModuleSlotTracker.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -430,6 +431,11 @@ void MIPrinter::print(const MachineOperand &Op, const TargetRegisterInfo *TRI) {
     OS << "%jump-table." << Op.getIndex();
     // TODO: Print target flags.
     break;
+  case MachineOperand::MO_ExternalSymbol:
+    OS << '$';
+    printLLVMNameWithoutPrefix(OS, Op.getSymbolName());
+    // TODO: Print the target flags.
+    break;
   case MachineOperand::MO_GlobalAddress:
     Op.getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
     // TODO: Print offset and target flags.
index 9856e70edaef0d2ce0f44c699568b135f7b2da12..0a8309eb2f2d6781e17ba08a97ee5ef6266f47cd 100644 (file)
@@ -322,6 +322,13 @@ MachineFunction::extractStoreMemRefs(MachineInstr::mmo_iterator Begin,
   return std::make_pair(Result, Result + Num);
 }
 
+const char *MachineFunction::createExternalSymbolName(StringRef Name) {
+  char *Dest = Allocator.Allocate<char>(Name.size() + 1);
+  std::copy(Name.begin(), Name.end(), Dest);
+  Dest[Name.size()] = 0;
+  return Dest;
+}
+
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 void MachineFunction::dump() const {
   print(dbgs());
diff --git a/test/CodeGen/MIR/X86/external-symbol-operands.mir b/test/CodeGen/MIR/X86/external-symbol-operands.mir
new file mode 100644 (file)
index 0000000..a786882
--- /dev/null
@@ -0,0 +1,60 @@
+# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
+# This test ensures that the MIR parser parses the external symbol machine
+# operands correctly.
+
+--- |
+  @__stack_chk_guard = external global i8*
+
+  define i32 @test(i32 %n) #0 {
+  entry:
+    %StackGuardSlot = alloca i8*
+    %StackGuard = load i8*, i8** @__stack_chk_guard
+    call void @llvm.stackprotector(i8* %StackGuard, i8** %StackGuardSlot)
+    %a = alloca [128 x i32], align 16
+    %idxprom = sext i32 %n to i64
+    %arrayidx = getelementptr inbounds [128 x i32], [128 x i32]* %a, i64 0, i64 %idxprom
+    %0 = load i32, i32* %arrayidx, align 4
+    call void @llvm.stackprotectorcheck(i8** @__stack_chk_guard)
+    ret i32 %0
+  }
+
+  declare void @llvm.stackprotector(i8*, i8**) #1
+
+  declare void @llvm.stackprotectorcheck(i8**) #1
+
+  attributes #0 = { ssp "stack-protector-buffer-size"="8" }
+  attributes #1 = { nounwind }
+
+...
+---
+name:            test
+tracksRegLiveness: true
+body:
+  - id:              0
+    name:            entry
+    successors:      [ '%bb.1.entry', '%bb.2.entry' ]
+    instructions:
+      - '%rsp = SUB64ri32 %rsp, 520, implicit-def %eflags'
+      - '%rcx = LOAD_STACK_GUARD'
+      - 'MOV64mr %rsp, 1, _, 512, _, %rcx'
+      - '%rax = MOVSX64rr32 %edi'
+      - '%eax = MOV32rm %rsp, 4, %rax, 0, _'
+      - 'CMP64rm %rcx, %rsp, 1, _, 512, _, implicit-def %eflags'
+      - 'JNE_1 %bb.2.entry, implicit %eflags'
+  - id:              1
+    name:            entry
+    instructions:
+      - '%rsp = ADD64ri32 %rsp, 520, implicit-def %eflags'
+      - 'RETQ %eax'
+  - id:              2
+    name:            entry
+    instructions:
+      # CHECK:      CALL64pcrel32 $__stack_chk_fail,
+      # CHECK-NEXT: CALL64pcrel32 $__stack_chk_fail.09-_,
+      # CHECK-NEXT: CALL64pcrel32 $"__stack_chk_fail$",
+      # CHECK-NEXT: CALL64pcrel32 $"$Quoted \09 External symbol \11 ",
+      - 'CALL64pcrel32 $__stack_chk_fail, csr_64, implicit %rsp, implicit-def %rsp'
+      - 'CALL64pcrel32 $__stack_chk_fail.09-_, csr_64, implicit %rsp, implicit-def %rsp'
+      - 'CALL64pcrel32 $__stack_chk_fail$, csr_64, implicit %rsp, implicit-def %rsp'
+      - 'CALL64pcrel32 $"$Quoted \09 External symbol \11 ", csr_64, implicit %rsp, implicit-def %rsp'
+...