Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
swiftshader
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
swiftshader
Commits
8b1a7051
Commit
8b1a7051
authored
Jun 17, 2015
by
John Porto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix a bug that would cause subzero to fail when --threads=0.
Creates a single TargetDataLowering. BUG= None R=stichnot@chromium.org Review URL:
https://codereview.chromium.org/1179313004
.
parent
8e32fed5
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
219 additions
and
172 deletions
+219
-172
IceCfgNode.cpp
src/IceCfgNode.cpp
+4
-1
IceCompiler.cpp
src/IceCompiler.cpp
+15
-8
IceELFObjectWriter.cpp
src/IceELFObjectWriter.cpp
+20
-14
IceELFObjectWriter.h
src/IceELFObjectWriter.h
+10
-12
IceGlobalContext.cpp
src/IceGlobalContext.cpp
+60
-72
IceGlobalContext.h
src/IceGlobalContext.h
+35
-0
IceTargetLowering.cpp
src/IceTargetLowering.cpp
+44
-20
IceTargetLowering.h
src/IceTargetLowering.h
+5
-3
IceTargetLoweringARM32.cpp
src/IceTargetLoweringARM32.cpp
+5
-5
IceTargetLoweringARM32.h
src/IceTargetLoweringARM32.h
+2
-1
IceTargetLoweringMIPS32.cpp
src/IceTargetLoweringMIPS32.cpp
+5
-5
IceTargetLoweringMIPS32.h
src/IceTargetLoweringMIPS32.h
+2
-1
IceTargetLoweringX8632.cpp
src/IceTargetLoweringX8632.cpp
+9
-10
IceTargetLoweringX8632.h
src/IceTargetLoweringX8632.h
+2
-1
IceTranslator.cpp
src/IceTranslator.cpp
+0
-10
IceTranslator.h
src/IceTranslator.h
+0
-7
elf_container.ll
tests_lit/llvm2ice_tests/elf_container.ll
+1
-2
No files found.
src/IceCfgNode.cpp
View file @
8b1a7051
...
...
@@ -1256,7 +1256,10 @@ void CfgNode::profileExecutionCount(VariableDeclaration *Var) {
assert
(
Info
!=
nullptr
);
Operand
*
RMWI64Name
=
Context
->
getConstantExternSym
(
RMW_I64
);
Constant
*
Counter
=
Context
->
getConstantExternSym
(
Var
->
getName
());
constexpr
RelocOffsetT
Offset
=
0
;
constexpr
bool
SuppressMangling
=
true
;
Constant
*
Counter
=
Context
->
getConstantSym
(
Offset
,
Var
->
getName
(),
SuppressMangling
);
Constant
*
AtomicRMWOp
=
Context
->
getConstantInt32
(
Intrinsics
::
AtomicAdd
);
Constant
*
One
=
Context
->
getConstantInt64
(
1
);
Constant
*
OrderAcquireRelease
=
...
...
src/IceCompiler.cpp
View file @
8b1a7051
...
...
@@ -141,21 +141,28 @@ void Compiler::run(const Ice::ClFlagsExtra &ExtraFlags, GlobalContext &Ctx,
}
Ctx
.
waitForWorkerThreads
();
Translator
->
transferErrorCode
();
Translator
->
emitConstants
();
if
(
Ctx
.
getFlags
().
getOutFileType
()
==
FT_Elf
)
{
TimerMarker
T1
(
Ice
::
TimerStack
::
TT_emit
,
&
Ctx
);
Ctx
.
getObjectWriter
()
->
setUndefinedSyms
(
Ctx
.
getConstantExternSyms
());
Ctx
.
getObjectWriter
()
->
writeNonUserSections
();
if
(
Translator
->
getErrorStatus
())
{
Ctx
.
getErrorStatus
()
->
assign
(
Translator
->
getErrorStatus
().
value
());
}
else
{
Ctx
.
lowerGlobals
(
"last"
);
Ctx
.
lowerProfileData
();
Ctx
.
lowerConstants
();
if
(
Ctx
.
getFlags
().
getOutFileType
()
==
FT_Elf
)
{
TimerMarker
T1
(
Ice
::
TimerStack
::
TT_emit
,
&
Ctx
);
Ctx
.
getObjectWriter
()
->
setUndefinedSyms
(
Ctx
.
getConstantExternSyms
());
Ctx
.
getObjectWriter
()
->
writeNonUserSections
();
}
}
if
(
Ctx
.
getFlags
().
getSubzeroTimingEnabled
())
Ctx
.
dumpTimers
();
if
(
Ctx
.
getFlags
().
getTimeEachFunction
())
{
const
bool
DumpCumulative
=
false
;
Ctx
.
dumpTimers
(
GlobalContext
::
TSK_Funcs
,
DumpCumulative
);
}
const
bool
FinalStats
=
true
;
const
expr
bool
FinalStats
=
true
;
Ctx
.
dumpStats
(
"_FINAL_"
,
FinalStats
);
}
...
...
src/IceELFObjectWriter.cpp
View file @
8b1a7051
...
...
@@ -285,7 +285,8 @@ void partitionGlobalsBySection(const VariableDeclarationList &Vars,
}
// end of anonymous namespace
void
ELFObjectWriter
::
writeDataSection
(
const
VariableDeclarationList
&
Vars
,
FixupKind
RelocationKind
)
{
FixupKind
RelocationKind
,
const
IceString
&
SectionSuffix
)
{
assert
(
!
SectionNumbersAssigned
);
VariableDeclarationList
VarsBySection
[
ELFObjectWriter
::
NumSectionTypes
];
for
(
auto
&
SectionList
:
VarsBySection
)
...
...
@@ -294,18 +295,28 @@ void ELFObjectWriter::writeDataSection(const VariableDeclarationList &Vars,
Ctx
.
getFlags
().
getTranslateOnly
());
size_t
I
=
0
;
for
(
auto
&
SectionList
:
VarsBySection
)
{
writeDataOfType
(
static_cast
<
SectionType
>
(
I
++
),
SectionList
,
RelocationKind
);
writeDataOfType
(
static_cast
<
SectionType
>
(
I
++
),
SectionList
,
RelocationKind
,
SectionSuffix
);
}
}
namespace
{
IceString
MangleSectionName
(
const
char
Base
[],
const
IceString
&
Suffix
)
{
if
(
Suffix
.
empty
())
return
Base
;
return
Base
+
(
"."
+
Suffix
);
}
}
// end of anonymous namespace
// TODO(jvoung): Handle fdata-sections.
void
ELFObjectWriter
::
writeDataOfType
(
SectionType
ST
,
const
VariableDeclarationList
&
Vars
,
FixupKind
RelocationKind
)
{
FixupKind
RelocationKind
,
const
IceString
&
SectionSuffix
)
{
if
(
Vars
.
empty
())
return
;
ELFDataSection
*
Section
;
ELFRelocationSection
*
RelSection
;
// TODO(jvoung): Handle fdata-sections.
IceString
SectionName
;
Elf64_Xword
ShAddralign
=
1
;
for
(
VariableDeclaration
*
Var
:
Vars
)
{
...
...
@@ -316,9 +327,7 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
// Lift this out, so it can be re-used if we do fdata-sections?
switch
(
ST
)
{
case
ROData
:
{
SectionName
=
".rodata"
;
// Only expecting to write the data sections all in one shot for now.
assert
(
RODataSections
.
empty
());
const
IceString
SectionName
=
MangleSectionName
(
".rodata"
,
SectionSuffix
);
const
Elf64_Xword
ShFlags
=
SHF_ALLOC
;
Section
=
createSection
<
ELFDataSection
>
(
SectionName
,
SHT_PROGBITS
,
ShFlags
,
ShAddralign
,
ShEntsize
);
...
...
@@ -329,8 +338,7 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
break
;
}
case
Data
:
{
SectionName
=
".data"
;
assert
(
DataSections
.
empty
());
const
IceString
SectionName
=
MangleSectionName
(
".data"
,
SectionSuffix
);
const
Elf64_Xword
ShFlags
=
SHF_ALLOC
|
SHF_WRITE
;
Section
=
createSection
<
ELFDataSection
>
(
SectionName
,
SHT_PROGBITS
,
ShFlags
,
ShAddralign
,
ShEntsize
);
...
...
@@ -341,8 +349,7 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
break
;
}
case
BSS
:
{
SectionName
=
".bss"
;
assert
(
BSSSections
.
empty
());
const
IceString
SectionName
=
MangleSectionName
(
".bss"
,
SectionSuffix
);
const
Elf64_Xword
ShFlags
=
SHF_ALLOC
|
SHF_WRITE
;
Section
=
createSection
<
ELFDataSection
>
(
SectionName
,
SHT_NOBITS
,
ShFlags
,
ShAddralign
,
ShEntsize
);
...
...
@@ -383,9 +390,8 @@ void ELFObjectWriter::writeDataOfType(SectionType ST,
for
(
VariableDeclaration
::
Initializer
*
Init
:
Var
->
getInitializers
())
{
switch
(
Init
->
getKind
())
{
case
VariableDeclaration
:
:
Initializer
::
DataInitializerKind
:
{
const
auto
Data
=
llvm
::
cast
<
VariableDeclaration
::
DataInitializer
>
(
Init
)
->
getContents
();
const
auto
Data
=
llvm
::
cast
<
VariableDeclaration
::
DataInitializer
>
(
Init
)
->
getContents
();
Section
->
appendData
(
Str
,
llvm
::
StringRef
(
Data
.
data
(),
Data
.
size
()));
break
;
}
...
...
src/IceELFObjectWriter.h
View file @
8b1a7051
...
...
@@ -30,11 +30,12 @@ namespace Ice {
// sections and write them out. Expected usage:
//
// (1) writeInitialELFHeader (invoke once)
// (2) writeDataSection (invoke once)
// (3) writeFunctionCode (must invoke once per function)
// (4) writeConstantPool (must invoke once per pooled primitive type)
// (5) setUndefinedSyms (invoke once)
// (6) writeNonUserSections (invoke once)
// (2) writeDataSection (may be invoked multiple times, as long as
// SectionSuffix is unique)
// (3) writeFunctionCode (must invoke once per function)
// (4) writeConstantPool (must invoke once per pooled primitive type)
// (5) setUndefinedSyms (invoke once)
// (6) writeNonUserSections (invoke once)
//
// The requirement for writeDataSection to be invoked only once can
// be relaxed if using -fdata-sections. The requirement to invoke only once
...
...
@@ -42,11 +43,6 @@ namespace Ice {
// SectionType are contiguous in the file. With -fdata-sections, each global
// variable is in a separate section and therefore the sections will be
// trivially contiguous.
//
// The motivation for requiring that writeFunctionCode happen after
// writeDataSection: to keep the .text and .data sections contiguous in the
// file. Having both -fdata-sections and -ffunction-sections does allow
// relaxing this requirement.
class
ELFObjectWriter
{
ELFObjectWriter
()
=
delete
;
ELFObjectWriter
(
const
ELFObjectWriter
&
)
=
delete
;
...
...
@@ -64,7 +60,8 @@ public:
// of each global's definition in the symbol table.
// Use the given target's RelocationKind for any relocations.
void
writeDataSection
(
const
VariableDeclarationList
&
Vars
,
FixupKind
RelocationKind
);
FixupKind
RelocationKind
,
const
IceString
&
SectionSuffix
);
// Copy data of a function's text section to file and note the offset of the
// symbol's definition in the symbol table.
...
...
@@ -151,7 +148,8 @@ private:
// SectionType, given the global variables Vars belonging to that SectionType.
void
writeDataOfType
(
SectionType
SectionType
,
const
VariableDeclarationList
&
Vars
,
FixupKind
RelocationKind
);
FixupKind
RelocationKind
,
const
IceString
&
SectionSuffix
);
// Write the final relocation sections given the final symbol table.
// May also be able to seek around the file and resolve function calls
...
...
src/IceGlobalContext.cpp
View file @
8b1a7051
...
...
@@ -222,7 +222,10 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
OptQ
(
/*Sequential=*/
Flags
.
isSequential
(),
/*MaxSize=*/
Flags
.
getNumTranslationThreads
()),
// EmitQ is allowed unlimited size.
EmitQ
(
/*Sequential=*/
Flags
.
isSequential
())
{
EmitQ
(
/*Sequential=*/
Flags
.
isSequential
()),
DataLowering
(
TargetDataLowering
::
createLowering
(
this
)),
HasSeenCode
(
false
),
ProfileBlockInfoVarDecl
(
VariableDeclaration
::
create
())
{
assert
(
OsDump
&&
"OsDump is not defined for GlobalContext"
);
assert
(
OsEmit
&&
"OsEmit is not defined for GlobalContext"
);
assert
(
OsError
&&
"OsError is not defined for GlobalContext"
);
...
...
@@ -254,6 +257,14 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
case
FT_Iasm
:
break
;
}
ProfileBlockInfoVarDecl
->
setAlignment
(
typeWidthInBytes
(
IceType_i64
));
ProfileBlockInfoVarDecl
->
setIsConstant
(
true
);
// Note: if you change this symbol, make sure to update
// runtime/szrt_profiler.c as well.
ProfileBlockInfoVarDecl
->
setName
(
"__Sz_block_profile_info"
);
ProfileBlockInfoVarDecl
->
setSuppressMangling
();
ProfileBlockInfoVarDecl
->
setLinkage
(
llvm
::
GlobalValue
::
ExternalLinkage
);
}
void
GlobalContext
::
translateFunctions
()
{
...
...
@@ -322,67 +333,16 @@ void GlobalContext::translateFunctions() {
namespace
{
// Adds an array of pointers to all the profiler-generated globals. The
// __Sz_profile_summary function iterates over this array for printing the
// profiling counters.
VariableDeclaration
*
blockProfileInfo
(
const
VariableDeclarationList
&
Globals
)
{
auto
*
Var
=
VariableDeclaration
::
create
();
Var
->
setAlignment
(
typeWidthInBytes
(
IceType_i64
));
Var
->
setIsConstant
(
true
);
// Note: if you change this symbol, make sure to update
// runtime/szrt_profiler.c as well.
Var
->
setName
(
"__Sz_block_profile_info"
);
Var
->
setSuppressMangling
();
Var
->
setLinkage
(
llvm
::
GlobalValue
::
ExternalLinkage
);
void
addBlockInfoPtrs
(
const
VariableDeclarationList
&
Globals
,
VariableDeclaration
*
ProfileBlockInfo
)
{
for
(
const
VariableDeclaration
*
Global
:
Globals
)
{
if
(
Cfg
::
isProfileGlobal
(
*
Global
))
{
constexpr
RelocOffsetT
BlockExecutionCounterOffset
=
0
;
Var
->
addInitializer
(
new
VariableDeclaration
::
RelocInitializer
(
Global
,
BlockExecutionCounterOffset
));
ProfileBlockInfo
->
addInitializer
(
new
VariableDeclaration
::
RelocInitializer
(
Global
,
BlockExecutionCounterOffset
));
}
}
// This adds a 64-bit sentinel entry to the end of our array. For 32-bit
// architectures this will waste 4 bytes.
const
SizeT
Sizeof64BitNullPtr
=
typeWidthInBytes
(
IceType_i64
);
Var
->
addInitializer
(
new
VariableDeclaration
::
ZeroInitializer
(
Sizeof64BitNullPtr
));
return
Var
;
}
void
addBlockProfileInfoArrayToGlobals
(
VariableDeclarationList
*
Globals
)
{
// Purposefully create the Var temp to prevent bugs in case the compiler
// reorders instructions in a way that Globals is extended before the call
// to profileInfoArray.
VariableDeclaration
*
Var
=
blockProfileInfo
(
*
Globals
);
Globals
->
push_back
(
Var
);
}
void
lowerGlobals
(
GlobalContext
*
Ctx
,
std
::
unique_ptr
<
VariableDeclarationList
>
VariableDeclarations
,
TargetDataLowering
*
DataLowering
)
{
TimerMarker
T
(
TimerStack
::
TT_emitGlobalInitializers
,
Ctx
);
const
bool
DumpGlobalVariables
=
ALLOW_DUMP
&&
Ctx
->
getFlags
().
getVerbose
()
&&
Ctx
->
getFlags
().
getVerboseFocusOn
().
empty
();
if
(
DumpGlobalVariables
)
{
OstreamLocker
L
(
Ctx
);
Ostream
&
Stream
=
Ctx
->
getStrDump
();
for
(
const
Ice
::
VariableDeclaration
*
Global
:
*
VariableDeclarations
)
{
Global
->
dump
(
Ctx
,
Stream
);
}
}
if
(
Ctx
->
getFlags
().
getDisableTranslation
())
return
;
// There should be no need to emit the block_profile_info array if profiling
// is disabled. In practice, given that szrt_profiler.o will always be
// embedded in the application, we need to add it. In a non-profiled build
// this array will only contain the nullptr terminator.
addBlockProfileInfoArrayToGlobals
(
VariableDeclarations
.
get
());
DataLowering
->
lowerGlobals
(
std
::
move
(
VariableDeclarations
));
}
// Ensure Pending is large enough that Pending[Index] is valid.
...
...
@@ -391,13 +351,6 @@ void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) {
Pending
.
resize
(
Index
+
1
);
}
void
addAllIfNotNull
(
std
::
unique_ptr
<
VariableDeclarationList
>
src
,
VariableDeclarationList
*
dst
)
{
if
(
src
!=
nullptr
)
{
dst
->
insert
(
dst
->
end
(),
src
->
begin
(),
src
->
end
());
}
}
}
// end of anonymous namespace
void
GlobalContext
::
emitFileHeader
()
{
...
...
@@ -411,6 +364,40 @@ void GlobalContext::emitFileHeader() {
}
}
void
GlobalContext
::
lowerConstants
()
{
DataLowering
->
lowerConstants
();
}
void
GlobalContext
::
lowerGlobals
(
const
IceString
&
SectionSuffix
)
{
TimerMarker
T
(
TimerStack
::
TT_emitGlobalInitializers
,
this
);
const
bool
DumpGlobalVariables
=
ALLOW_DUMP
&&
Flags
.
getVerbose
()
&&
Flags
.
getVerboseFocusOn
().
empty
();
if
(
DumpGlobalVariables
)
{
OstreamLocker
L
(
this
);
Ostream
&
Stream
=
getStrDump
();
for
(
const
Ice
::
VariableDeclaration
*
Global
:
Globals
)
{
Global
->
dump
(
this
,
Stream
);
}
}
if
(
Flags
.
getDisableTranslation
())
return
;
addBlockInfoPtrs
(
Globals
,
ProfileBlockInfoVarDecl
.
get
());
DataLowering
->
lowerGlobals
(
Globals
,
SectionSuffix
);
Globals
.
clear
();
}
void
GlobalContext
::
lowerProfileData
()
{
// This adds a 64-bit sentinel entry to the end of our array. For 32-bit
// architectures this will waste 4 bytes.
const
SizeT
Sizeof64BitNullPtr
=
typeWidthInBytes
(
IceType_i64
);
ProfileBlockInfoVarDecl
->
addInitializer
(
new
VariableDeclaration
::
ZeroInitializer
(
Sizeof64BitNullPtr
));
Globals
.
push_back
(
ProfileBlockInfoVarDecl
.
get
());
constexpr
char
ProfileDataSection
[]
=
"$sz_profiler$"
;
lowerGlobals
(
ProfileDataSection
);
}
void
GlobalContext
::
emitItems
()
{
const
bool
Threaded
=
!
getFlags
().
isSequential
();
// Pending is a vector containing the reassembled, ordered list of
...
...
@@ -419,8 +406,6 @@ void GlobalContext::emitItems() {
// the work queue, and if it's not the item we're waiting for, we
// insert it into Pending and repeat. The work item is deleted
// after it is processed.
std
::
unique_ptr
<
VariableDeclarationList
>
GlobalInits
(
new
VariableDeclarationList
());
std
::
vector
<
EmitterWorkItem
*>
Pending
;
uint32_t
DesiredSequenceNumber
=
getFirstSequenceNumber
();
while
(
true
)
{
...
...
@@ -444,10 +429,12 @@ void GlobalContext::emitItems() {
case
EmitterWorkItem
:
:
WI_Nop
:
break
;
case
EmitterWorkItem
:
:
WI_GlobalInits
:
{
a
ddAllIfNotNull
(
Item
->
getGlobalInits
(),
GlobalInits
.
get
());
a
ccumulateGlobals
(
Item
->
getGlobalInits
());
}
break
;
case
EmitterWorkItem
:
:
WI_Asm
:
{
addAllIfNotNull
(
Item
->
getGlobalInits
(),
GlobalInits
.
get
());
lowerGlobalsIfNoCodeHasBeenSeen
();
accumulateGlobals
(
Item
->
getGlobalInits
());
std
::
unique_ptr
<
Assembler
>
Asm
=
Item
->
getAsm
();
Asm
->
alignFunction
();
IceString
MangledName
=
mangleName
(
Asm
->
getFunctionName
());
...
...
@@ -469,8 +456,8 @@ void GlobalContext::emitItems() {
case
EmitterWorkItem
:
:
WI_Cfg
:
{
if
(
!
ALLOW_DUMP
)
llvm
::
report_fatal_error
(
"WI_Cfg work item created inappropriately"
);
a
ddAllIfNotNull
(
Item
->
getGlobalInits
(),
GlobalInits
.
get
());
lowerGlobalsIfNoCodeHasBeenSeen
();
a
ccumulateGlobals
(
Item
->
getGlobalInits
());
assert
(
getFlags
().
getOutFileType
()
==
FT_Asm
);
std
::
unique_ptr
<
Cfg
>
Func
=
Item
->
getCfg
();
...
...
@@ -485,8 +472,9 @@ void GlobalContext::emitItems() {
}
}
lowerGlobals
(
this
,
std
::
move
(
GlobalInits
),
TargetDataLowering
::
createLowering
(
this
).
get
());
// In case there are no code to be generated, we invoke the conditional
// lowerGlobals again -- this is a no-op if code has been emitted.
lowerGlobalsIfNoCodeHasBeenSeen
();
}
// Scan a string for S[0-9A-Z]*_ patterns and replace them with
...
...
src/IceGlobalContext.h
View file @
8b1a7051
...
...
@@ -303,6 +303,8 @@ public:
// Emit file header for output file.
void
emitFileHeader
();
void
lowerConstants
();
void
emitQueueBlockingPush
(
EmitterWorkItem
*
Item
);
EmitterWorkItem
*
emitQueueBlockingPop
();
void
emitQueueNotifyEnd
()
{
EmitQ
.
notifyEnd
();
}
...
...
@@ -380,6 +382,13 @@ public:
// until the queue is empty.
void
emitItems
();
// Uses DataLowering to lower Globals. As a side effect, clears the Globals
// array.
void
lowerGlobals
(
const
IceString
&
SectionSuffix
);
// Lowers the profile information.
void
lowerProfileData
();
// Utility function to match a symbol name against a match string.
// This is used in a few cases where we want to take some action on
// a particular function or symbol based on a command-line argument,
...
...
@@ -432,9 +441,22 @@ private:
Intrinsics
IntrinsicsInfo
;
const
ClFlags
&
Flags
;
RandomNumberGenerator
RNG
;
// TODO(stichnot): Move into Cfg.
// TODO(jpp): move to EmitterContext.
std
::
unique_ptr
<
ELFObjectWriter
>
ObjectWriter
;
BoundedProducerConsumerQueue
<
Cfg
>
OptQ
;
BoundedProducerConsumerQueue
<
EmitterWorkItem
>
EmitQ
;
// DataLowering is only ever used by a single thread at a time (either in
// emitItems(), or in IceCompiler::run before the compilation is over.)
// TODO(jpp): move to EmitterContext.
std
::
unique_ptr
<
TargetDataLowering
>
DataLowering
;
// If !HasEmittedCode, SubZero will accumulate all Globals (which are "true"
// program global variables) until the first code WorkItem is seen.
// TODO(jpp): move to EmitterContext.
bool
HasSeenCode
;
// TODO(jpp): move to EmitterContext.
VariableDeclarationList
Globals
;
// TODO(jpp): move to EmitterContext.
std
::
unique_ptr
<
VariableDeclaration
>
ProfileBlockInfoVarDecl
;
LockedPtr
<
ArenaAllocator
<>>
getAllocator
()
{
return
LockedPtr
<
ArenaAllocator
<>>
(
&
Allocator
,
&
AllocLock
);
...
...
@@ -449,6 +471,19 @@ private:
return
LockedPtr
<
TimerList
>
(
&
Timers
,
&
TimerLock
);
}
void
accumulateGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Globls
)
{
if
(
Globls
!=
nullptr
)
Globals
.
insert
(
Globals
.
end
(),
Globls
->
begin
(),
Globls
->
end
());
}
void
lowerGlobalsIfNoCodeHasBeenSeen
()
{
if
(
HasSeenCode
)
return
;
constexpr
char
NoSuffix
[]
=
""
;
lowerGlobals
(
NoSuffix
);
HasSeenCode
=
true
;
}
llvm
::
SmallVector
<
ThreadContext
*
,
128
>
AllThreadContexts
;
llvm
::
SmallVector
<
std
::
thread
,
128
>
TranslationThreads
;
llvm
::
SmallVector
<
std
::
thread
,
128
>
EmitterThreads
;
...
...
src/IceTargetLowering.cpp
View file @
8b1a7051
...
...
@@ -446,40 +446,63 @@ TargetDataLowering::createLowering(GlobalContext *Ctx) {
TargetDataLowering
::~
TargetDataLowering
()
{}
void
TargetDataLowering
::
emitGlobal
(
const
VariableDeclaration
&
Var
)
{
namespace
{
// dataSectionSuffix decides whether to use SectionSuffix or MangledVarName as
// data section suffix. Essentially, when using separate data sections for
// globals SectionSuffix is not necessary.
IceString
dataSectionSuffix
(
const
IceString
&
SectionSuffix
,
const
IceString
&
MangledVarName
,
const
bool
DataSections
)
{
if
(
SectionSuffix
.
empty
()
&&
!
DataSections
)
{
return
""
;
}
if
(
DataSections
)
{
// With data sections we don't need to use the SectionSuffix.
return
"."
+
MangledVarName
;
}
assert
(
!
SectionSuffix
.
empty
());
return
"."
+
SectionSuffix
;
}
}
// end of anonymous namespace
void
TargetDataLowering
::
emitGlobal
(
const
VariableDeclaration
&
Var
,
const
IceString
&
SectionSuffix
)
{
if
(
!
ALLOW_DUMP
)
return
;
// If external and not initialized, this must be a cross test.
// Don't generate a declaration for such cases.
bool
IsExternal
=
Var
.
isExternal
()
||
Ctx
->
getFlags
().
getDisableInternal
();
const
bool
IsExternal
=
Var
.
isExternal
()
||
Ctx
->
getFlags
().
getDisableInternal
();
if
(
IsExternal
&&
!
Var
.
hasInitializer
())
return
;
Ostream
&
Str
=
Ctx
->
getStrEmit
();
const
VariableDeclaration
::
InitializerListType
&
Initializers
=
Var
.
getInitializers
();
bool
HasNonzeroInitializer
=
Var
.
hasNonzeroInitializer
();
bool
IsConstant
=
Var
.
getIsConstant
();
uint32_t
Align
=
Var
.
getAlignment
();
SizeT
Size
=
Var
.
getNumBytes
();
IceString
MangledName
=
Var
.
mangleName
(
Ctx
);
IceString
SectionSuffix
=
""
;
if
(
Ctx
->
getFlags
().
getDataSections
())
SectionSuffix
=
"."
+
MangledName
;
const
bool
HasNonzeroInitializer
=
Var
.
hasNonzeroInitializer
();
const
bool
IsConstant
=
Var
.
getIsConstant
();
const
SizeT
Size
=
Var
.
getNumBytes
();
const
IceString
MangledName
=
Var
.
mangleName
(
Ctx
);
Str
<<
"
\t
.type
\t
"
<<
MangledName
<<
",%object
\n
"
;
const
bool
UseDataSections
=
Ctx
->
getFlags
().
getDataSections
();
const
IceString
Suffix
=
dataSectionSuffix
(
SectionSuffix
,
MangledName
,
UseDataSections
);
if
(
IsConstant
)
Str
<<
"
\t
.section
\t
.rodata"
<<
S
ectionS
uffix
<<
",
\"
a
\"
,%progbits
\n
"
;
Str
<<
"
\t
.section
\t
.rodata"
<<
Suffix
<<
",
\"
a
\"
,%progbits
\n
"
;
else
if
(
HasNonzeroInitializer
)
Str
<<
"
\t
.section
\t
.data"
<<
S
ectionS
uffix
<<
",
\"
aw
\"
,%progbits
\n
"
;
Str
<<
"
\t
.section
\t
.data"
<<
Suffix
<<
",
\"
aw
\"
,%progbits
\n
"
;
else
Str
<<
"
\t
.section
\t
.bss"
<<
S
ectionS
uffix
<<
",
\"
aw
\"
,%nobits
\n
"
;
Str
<<
"
\t
.section
\t
.bss"
<<
Suffix
<<
",
\"
aw
\"
,%nobits
\n
"
;
if
(
IsExternal
)
Str
<<
"
\t
.globl
\t
"
<<
MangledName
<<
"
\n
"
;
const
uint32_t
Align
=
Var
.
getAlignment
();
if
(
Align
>
1
)
{
assert
(
llvm
::
isPowerOf2_32
(
Align
));
// Use the .p2align directive, since the .align N directive can either
...
...
@@ -490,11 +513,11 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var) {
Str
<<
MangledName
<<
":
\n
"
;
if
(
HasNonzeroInitializer
)
{
for
(
VariableDeclaration
::
Initializer
*
Init
:
Initializers
)
{
for
(
VariableDeclaration
::
Initializer
*
Init
:
Var
.
getInitializers
()
)
{
switch
(
Init
->
getKind
())
{
case
VariableDeclaration
:
:
Initializer
::
DataInitializerKind
:
{
const
auto
Data
=
llvm
::
cast
<
VariableDeclaration
::
DataInitializer
>
(
Init
)
->
getContents
();
const
auto
&
Data
=
llvm
::
cast
<
VariableDeclaration
::
DataInitializer
>
(
Init
)
->
getContents
();
for
(
SizeT
i
=
0
;
i
<
Init
->
getNumBytes
();
++
i
)
{
Str
<<
"
\t
.byte
\t
"
<<
(((
unsigned
)
Data
[
i
])
&
0xff
)
<<
"
\n
"
;
}
...
...
@@ -504,7 +527,7 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var) {
Str
<<
"
\t
.zero
\t
"
<<
Init
->
getNumBytes
()
<<
"
\n
"
;
break
;
case
VariableDeclaration
:
:
Initializer
::
RelocInitializerKind
:
{
const
auto
Reloc
=
const
auto
*
Reloc
=
llvm
::
cast
<
VariableDeclaration
::
RelocInitializer
>
(
Init
);
Str
<<
"
\t
"
<<
getEmit32Directive
()
<<
"
\t
"
;
Str
<<
Reloc
->
getDeclaration
()
->
mangleName
(
Ctx
);
...
...
@@ -519,12 +542,13 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var) {
}
}
}
}
else
}
else
{
// NOTE: for non-constant zero initializers, this is BSS (no bits),
// so an ELF writer would not write to the file, and only track
// virtual offsets, but the .s writer still needs this .zero and
// cannot simply use the .size to advance offsets.
Str
<<
"
\t
.zero
\t
"
<<
Size
<<
"
\n
"
;
}
Str
<<
"
\t
.size
\t
"
<<
MangledName
<<
", "
<<
Size
<<
"
\n
"
;
}
...
...
src/IceTargetLowering.h
View file @
8b1a7051
...
...
@@ -380,16 +380,18 @@ public:
static
std
::
unique_ptr
<
TargetDataLowering
>
createLowering
(
GlobalContext
*
Ctx
);
virtual
~
TargetDataLowering
();
virtual
void
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
=
0
;
virtual
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
=
0
;
virtual
void
lowerConstants
()
=
0
;
protected
:
void
emitGlobal
(
const
VariableDeclaration
&
Var
);
void
emitGlobal
(
const
VariableDeclaration
&
Var
,
const
IceString
&
SectionSuffix
);
// For now, we assume .long is the right directive for emitting 4 byte
// emit global relocations. However, LLVM MIPS usually uses .4byte instead.
// Perhaps there is some difference when the location is unaligned.
const
char
*
getEmit32Directive
()
{
return
".long"
;
}
static
const
char
*
getEmit32Directive
()
{
return
".long"
;
}
explicit
TargetDataLowering
(
GlobalContext
*
Ctx
)
:
Ctx
(
Ctx
)
{}
GlobalContext
*
Ctx
;
...
...
src/IceTargetLoweringARM32.cpp
View file @
8b1a7051
...
...
@@ -2207,20 +2207,20 @@ void TargetARM32::emit(const ConstantUndef *) const {
TargetDataARM32
::
TargetDataARM32
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
)
{}
void
TargetDataARM32
::
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
{
void
TargetDataARM32
::
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
{
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeDataSection
(
*
Vars
,
llvm
::
ELF
::
R_ARM_ABS32
);
Writer
->
writeDataSection
(
Vars
,
llvm
::
ELF
::
R_ARM_ABS32
,
SectionSuffix
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
const
IceString
&
TranslateOnly
=
Ctx
->
getFlags
().
getTranslateOnly
();
OstreamLocker
L
(
Ctx
);
for
(
const
VariableDeclaration
*
Var
:
*
Vars
)
{
for
(
const
VariableDeclaration
*
Var
:
Vars
)
{
if
(
GlobalContext
::
matchSymbolName
(
Var
->
getName
(),
TranslateOnly
))
{
emitGlobal
(
*
Var
);
emitGlobal
(
*
Var
,
SectionSuffix
);
}
}
}
break
;
...
...
src/IceTargetLoweringARM32.h
View file @
8b1a7051
...
...
@@ -323,7 +323,8 @@ public:
return
std
::
unique_ptr
<
TargetDataLowering
>
(
new
TargetDataARM32
(
Ctx
));
}
void
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
override
;
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
override
;
void
lowerConstants
()
override
;
protected
:
...
...
src/IceTargetLoweringMIPS32.cpp
View file @
8b1a7051
...
...
@@ -671,20 +671,20 @@ void ConstantUndef::emit(GlobalContext *) const {
TargetDataMIPS32
::
TargetDataMIPS32
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
)
{}
void
TargetDataMIPS32
::
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
{
void
TargetDataMIPS32
::
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
{
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeDataSection
(
*
Vars
,
llvm
::
ELF
::
R_MIPS_GLOB_DAT
);
Writer
->
writeDataSection
(
Vars
,
llvm
::
ELF
::
R_MIPS_GLOB_DAT
,
SectionSuffix
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
const
IceString
&
TranslateOnly
=
Ctx
->
getFlags
().
getTranslateOnly
();
OstreamLocker
L
(
Ctx
);
for
(
const
VariableDeclaration
*
Var
:
*
Vars
)
{
for
(
const
VariableDeclaration
*
Var
:
Vars
)
{
if
(
GlobalContext
::
matchSymbolName
(
Var
->
getName
(),
TranslateOnly
))
{
emitGlobal
(
*
Var
);
emitGlobal
(
*
Var
,
SectionSuffix
);
}
}
}
break
;
...
...
src/IceTargetLoweringMIPS32.h
View file @
8b1a7051
...
...
@@ -137,7 +137,8 @@ public:
return
std
::
unique_ptr
<
TargetDataLowering
>
(
new
TargetDataMIPS32
(
Ctx
));
}
void
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
override
;
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
override
;
void
lowerConstants
()
override
;
protected
:
...
...
src/IceTargetLoweringX8632.cpp
View file @
8b1a7051
...
...
@@ -3296,11 +3296,10 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Func
->
setError
(
"Unexpected memory ordering for AtomicRMW"
);
return
;
}
lowerAtomicRMW
(
Instr
->
getDest
(),
static_cast
<
uint32_t
>
(
llvm
::
cast
<
ConstantInteger32
>
(
Instr
->
getArg
(
0
))
->
getValue
()),
Instr
->
getArg
(
1
),
Instr
->
getArg
(
2
));
lowerAtomicRMW
(
Instr
->
getDest
(),
static_cast
<
uint32_t
>
(
llvm
::
cast
<
ConstantInteger32
>
(
Instr
->
getArg
(
0
))
->
getValue
()),
Instr
->
getArg
(
1
),
Instr
->
getArg
(
2
));
return
;
case
Intrinsics
:
:
AtomicStore
:
{
if
(
!
Intrinsics
::
isMemoryOrderValid
(
...
...
@@ -5021,20 +5020,20 @@ void TargetX8632::emit(const ConstantUndef *) const {
TargetDataX8632
::
TargetDataX8632
(
GlobalContext
*
Ctx
)
:
TargetDataLowering
(
Ctx
)
{}
void
TargetDataX8632
::
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
{
void
TargetDataX8632
::
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
{
switch
(
Ctx
->
getFlags
().
getOutFileType
())
{
case
FT_Elf
:
{
ELFObjectWriter
*
Writer
=
Ctx
->
getObjectWriter
();
Writer
->
writeDataSection
(
*
Vars
,
llvm
::
ELF
::
R_386_32
);
Writer
->
writeDataSection
(
Vars
,
llvm
::
ELF
::
R_386_32
,
SectionSuffix
);
}
break
;
case
FT_Asm
:
case
FT_Iasm
:
{
const
IceString
&
TranslateOnly
=
Ctx
->
getFlags
().
getTranslateOnly
();
OstreamLocker
L
(
Ctx
);
for
(
const
VariableDeclaration
*
Var
:
*
Vars
)
{
for
(
const
VariableDeclaration
*
Var
:
Vars
)
{
if
(
GlobalContext
::
matchSymbolName
(
Var
->
getName
(),
TranslateOnly
))
{
emitGlobal
(
*
Var
);
emitGlobal
(
*
Var
,
SectionSuffix
);
}
}
}
break
;
...
...
src/IceTargetLoweringX8632.h
View file @
8b1a7051
...
...
@@ -587,7 +587,8 @@ public:
return
std
::
unique_ptr
<
TargetDataLowering
>
(
new
TargetDataX8632
(
Ctx
));
}
void
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
Vars
)
override
;
void
lowerGlobals
(
const
VariableDeclarationList
&
Vars
,
const
IceString
&
SectionSuffix
)
override
;
void
lowerConstants
()
override
;
protected
:
...
...
src/IceTranslator.cpp
View file @
8b1a7051
...
...
@@ -57,16 +57,6 @@ void Translator::translateFcn(std::unique_ptr<Cfg> Func) {
Ctx
->
optQueueBlockingPush
(
std
::
move
(
Func
));
}
void
Translator
::
emitConstants
()
{
if
(
!
getErrorStatus
())
TargetDataLowering
::
createLowering
(
Ctx
)
->
lowerConstants
();
}
void
Translator
::
transferErrorCode
()
const
{
if
(
getErrorStatus
())
Ctx
->
getErrorStatus
()
->
assign
(
getErrorStatus
().
value
());
}
void
Translator
::
lowerGlobals
(
std
::
unique_ptr
<
VariableDeclarationList
>
VariableDeclarations
)
{
EmitterWorkItem
*
Item
=
new
EmitterWorkItem
(
getNextSequenceNumber
(),
...
...
src/IceTranslator.h
View file @
8b1a7051
...
...
@@ -48,13 +48,6 @@ public:
/// Takes ownership of Func.
void
translateFcn
(
std
::
unique_ptr
<
Cfg
>
Func
);
/// Emits the constant pool.
void
emitConstants
();
/// If there was an error during bitcode reading/parsing, copy the
/// error code into the GlobalContext.
void
transferErrorCode
()
const
;
/// Lowers the given list of global addresses to target. Generates
/// list of corresponding variable declarations.
void
...
...
tests_lit/llvm2ice_tests/elf_container.ll
View file @
8b1a7051
...
...
@@ -270,8 +270,7 @@ define void @_start(i32) {
; CHECK: ]
; CHECK: Address: 0x0
; CHECK: Offset: 0x{{[1-9A-F][0-9A-F]*}}
; Size is 56 instead of 48 due to __Sz_block_profile_info .
; CHECK: Size: 56
; CHECK: Size: 48
; CHECK: Link: 0
; CHECK: Info: 0
; CHECK: AddressAlignment: 32
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment