Remove const_cast for STI when parsing inline asm
authorDavid Peixotto <dpeixott@codeaurora.org>
Thu, 6 Feb 2014 18:19:40 +0000 (18:19 +0000)
committerDavid Peixotto <dpeixott@codeaurora.org>
Thu, 6 Feb 2014 18:19:40 +0000 (18:19 +0000)
In a previous commit (r199818) we added a const_cast to an existing
subtarget info instead of creating a new one so that we could reuse
it when creating the TargetAsmParser for parsing inline assembly.
This cast was necessary because we needed to reuse the existing STI
to avoid generating incorrect code when the inline asm contained
mode-switching directives (e.g. .code 16).

The root cause of the failure was that there was an implicit sharing
of the STI between the parser and the MCCodeEmitter. To fix a
different but related issue, we now explicitly pass the STI to the
MCCodeEmitter (see commits r200345-r200351).

The const_cast is no longer necessary and we can now create a fresh
STI for the inline asm parser to use.

Differential Revision: http://llvm-reviews.chandlerc.com/D2709

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

include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMAsmPrinter.h

index f83d96783c7ada5cb5323674dd5509d6a873d26d..79c7fec3ce433856571330073713684749c077e3 100644 (file)
@@ -475,7 +475,7 @@ namespace llvm {
     /// \p EndInfo   - the final subtarget info after parsing the inline asm,
     ///                or NULL if the value is unknown.
     virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
-                                  MCSubtargetInfo *EndInfo) const;
+                                  const MCSubtargetInfo *EndInfo) const;
 
   private:
     /// Private state for PrintSpecial()
index aece69bca632547a635d72619a195aafe8a7979e..8badf429d2dd3d5fd67a7e4ebae2c738d41ad621 100644 (file)
@@ -117,14 +117,17 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
                                                   OutContext, OutStreamer,
                                                   *MAI));
 
-  // Reuse the existing Subtarget, because the AsmParser may need to
-  // modify it.  For example, when switching between ARM and
-  // Thumb mode.
-  MCSubtargetInfo* STI =
-    const_cast<MCSubtargetInfo*>(&TM.getSubtarget<MCSubtargetInfo>());
-
-  // Preserve a copy of the original STI because the parser may modify it.
-  // The target can restore the original state in emitInlineAsmEnd().
+  // Initialize the parser with a fresh subtarget info. It is better to use a
+  // new STI here because the parser may modify it and we do not want those
+  // modifications to persist after parsing the inlineasm. The modifications
+  // made by the parser will be seen by the code emitters because it passes
+  // the current STI down to the EncodeInstruction() method.
+  OwningPtr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
+      TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString()));
+
+  // Preserve a copy of the original STI because the parser may modify it.  For
+  // example, when switching between arm and thumb mode. If the target needs to
+  // emit code to return to the original state it can do so in emitInlineAsmEnd().
   MCSubtargetInfo STIOrig = *STI;
 
   OwningPtr<MCTargetAsmParser>
@@ -138,7 +141,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
   // Don't implicitly switch to the text section before the asm.
   int Res = Parser->Run(/*NoInitialTextSection*/ true,
                         /*NoFinalize*/ true);
-  emitInlineAsmEnd(STIOrig, STI);
+  emitInlineAsmEnd(STIOrig, STI.get());
   if (Res && !HasDiagHandler)
     report_fatal_error("Error parsing inline asm\n");
 }
@@ -550,4 +553,4 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
 }
 
 void AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
-                                  MCSubtargetInfo *EndInfo) const {}
+                                  const MCSubtargetInfo *EndInfo) const {}
index d0aad327c40f74256993bc9adebf36bd9c3deda5..82355063221a893741a35bf139d0fa0adde8b162 100644 (file)
@@ -443,14 +443,12 @@ static bool isThumb(const MCSubtargetInfo& STI) {
 }
 
 void ARMAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
-                                     MCSubtargetInfo *EndInfo) const {
+                                     const MCSubtargetInfo *EndInfo) const {
   // If either end mode is unknown (EndInfo == NULL) or different than
   // the start mode, then restore the start mode.
   const bool WasThumb = isThumb(StartInfo);
   if (EndInfo == NULL || WasThumb != isThumb(*EndInfo)) {
     OutStreamer.EmitAssemblerFlag(WasThumb ? MCAF_Code16 : MCAF_Code32);
-    if (EndInfo)
-      EndInfo->ToggleFeature(ARM::ModeThumb);
   }
 }
 
index d1c0e09e6109084dc6def429a88fb641a05395f8..fe17d996b73b3e4a2ca2d3b069ccb0e1b2509636 100644 (file)
@@ -64,7 +64,8 @@ public:
                                      raw_ostream &O) LLVM_OVERRIDE;
 
   virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
-                                MCSubtargetInfo *EndInfo) const LLVM_OVERRIDE;
+                                const MCSubtargetInfo *EndInfo) const
+      LLVM_OVERRIDE;
 
   void EmitJumpTable(const MachineInstr *MI);
   void EmitJump2Table(const MachineInstr *MI);