Target type size
This commit is contained in:
parent
631fab7431
commit
6b716fbd56
@ -34,3 +34,13 @@ Custom UNSPECs can not get through vregs or a few later passes
|
|||||||
-> architecture specific, dynamic operands though
|
-> architecture specific, dynamic operands though
|
||||||
-> can not get optimized (O1+ does optimizations in RTL, mostly after vregs)
|
-> can not get optimized (O1+ does optimizations in RTL, mostly after vregs)
|
||||||
-> could replace asm with normal "set" RTL close to final pass to remove architecture dependence
|
-> could replace asm with normal "set" RTL close to final pass to remove architecture dependence
|
||||||
|
|
||||||
|
Plugin is per compilation unit
|
||||||
|
-> static label counters start at 0 for each
|
||||||
|
-> labels are local symbols in symbtab
|
||||||
|
-> symtab entries like "df *ABS* 0000000000000000 main.c" indicate block begin for new file
|
||||||
|
-> "main.c" and "sub/main.c" both only specify "main.c" (no way to differentiate)
|
||||||
|
-> emit UID symbol per CU to match symbol block to unique label set
|
||||||
|
-> structs with same name can habe different definitions in different CUs (disallow this for now)
|
||||||
|
-> anonymous structs can not really be matched between CUs without type hash (disallow this for now)
|
||||||
|
-> later, use hash(type) to match structs between CUs to randomize as one
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<sourcefile>.spslr:
|
<sourcefile>.spslr:
|
||||||
|
|
||||||
SPSLR_FINALIZE_HEADER <CU filename> <CU uid symbol>
|
SPSLR_FINALIZE_HEADER <CU filename> <CU uid symbol>
|
||||||
target <hash> <local uid> <size> <field count>
|
target <name> <local uid> <size> <field count>
|
||||||
f <offset> <size> <flags>
|
f <offset> <size> <flags>
|
||||||
f <offset> <size> <flags>
|
f <offset> <size> <flags>
|
||||||
...
|
...
|
||||||
@ -20,7 +20,8 @@ dpin <symbol> <offset> <level> <target uid>
|
|||||||
|
|
||||||
Datapins for same var/symbol are randomized in order of their level, from bottom of nest to top
|
Datapins for same var/symbol are randomized in order of their level, from bottom of nest to top
|
||||||
The CU uid symbol helps differentiating between e.g. "file.c" and "sub/file.c" (symbtab has no idea)
|
The CU uid symbol helps differentiating between e.g. "file.c" and "sub/file.c" (symbtab has no idea)
|
||||||
Between CUs, types with the same hash are considered to be the same type
|
Between CUs, types with the same name HAVE TO HAVE the same layout -> randomized together
|
||||||
|
To begin with, anonymous types are not allowed for randomization (later solved with hash(type) instead of name)!
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,9 @@ void on_finish_unit(void* plugin_data, void* user_data) {
|
|||||||
|
|
||||||
std::cout << "Finishing unit \"" << lbasename(main_input_filename) << "\" ..." << std::endl;
|
std::cout << "Finishing unit \"" << lbasename(main_input_filename) << "\" ..." << std::endl;
|
||||||
|
|
||||||
|
for (const auto& [uid, target] : TargetType::all())
|
||||||
|
std::cout << " Target " << uid << " -> \"" << target.name() << "\" (" << target.size() << ")" << std::endl;
|
||||||
|
|
||||||
for (const DataPin& dpin : dpins()) {
|
for (const DataPin& dpin : dpins()) {
|
||||||
std::cout << " Data pin at symbol \"" << dpin.symbol << "\":" << std::endl;
|
std::cout << " Data pin at symbol \"" << dpin.symbol << "\":" << std::endl;
|
||||||
for (const DataPin::Component& c : dpin.components)
|
for (const DataPin::Component& c : dpin.components)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -27,6 +28,7 @@ private:
|
|||||||
UID m_uid;
|
UID m_uid;
|
||||||
std::size_t m_flags;
|
std::size_t m_flags;
|
||||||
tree m_main_variant;
|
tree m_main_variant;
|
||||||
|
std::size_t m_size;
|
||||||
|
|
||||||
// Fields are identified by their offsets
|
// Fields are identified by their offsets
|
||||||
std::map<std::size_t, Field> m_fields;
|
std::map<std::size_t, Field> m_fields;
|
||||||
@ -44,12 +46,14 @@ public:
|
|||||||
std::string name() const;
|
std::string name() const;
|
||||||
const Field* field(std::size_t off, bool exact = true) const;
|
const Field* field(std::size_t off, bool exact = true) const;
|
||||||
UID uid() const;
|
UID uid() const;
|
||||||
|
std::size_t size() const;
|
||||||
|
|
||||||
static void add(tree t);
|
static void add(tree t);
|
||||||
static std::size_t count();
|
static std::size_t count();
|
||||||
static const TargetType* find(tree t); // O(n)
|
static const TargetType* find(tree t); // O(n)
|
||||||
static const TargetType* find(UID uid); // O(1)
|
static const TargetType* find(UID uid); // O(1)
|
||||||
static bool reference(tree ref, UID& target, std::size_t& offset);
|
static bool reference(tree ref, UID& target, std::size_t& offset);
|
||||||
|
static const std::unordered_map<UID, TargetType>& all();
|
||||||
private:
|
private:
|
||||||
friend void on_finish_type(void*, void*);
|
friend void on_finish_type(void*, void*);
|
||||||
bool fetch_fields(bool redo = false);
|
bool fetch_fields(bool redo = false);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include <stage0.h>
|
#include <stage0.h>
|
||||||
#include <unordered_map>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <safe-langhooks.h>
|
#include <safe-langhooks.h>
|
||||||
@ -14,7 +13,7 @@ static tree get_record_main_variant(tree t) {
|
|||||||
return TYPE_MAIN_VARIANT(t);
|
return TYPE_MAIN_VARIANT(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetType::TargetType(tree t) : m_uid{ UID_INVALID }, m_flags{ 0 } {
|
TargetType::TargetType(tree t) : m_uid{ UID_INVALID }, m_flags{ 0 }, m_size{ 0 } {
|
||||||
if (!(m_main_variant = get_record_main_variant(t)))
|
if (!(m_main_variant = get_record_main_variant(t)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -75,6 +74,13 @@ UID TargetType::uid() const {
|
|||||||
return m_uid;
|
return m_uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t TargetType::size() const {
|
||||||
|
if (!valid() || !(m_flags & FLAG_FIELDS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
void TargetType::add(tree t) {
|
void TargetType::add(tree t) {
|
||||||
if (find(t) != nullptr)
|
if (find(t) != nullptr)
|
||||||
return;
|
return;
|
||||||
@ -206,6 +212,10 @@ bool TargetType::reference(tree ref, UID& target, std::size_t& offset) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::unordered_map<UID, TargetType>& TargetType::all() {
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
static bool foreach_record_field(tree t, std::function<bool(const TargetType::Field&)> callback) {
|
static bool foreach_record_field(tree t, std::function<bool(const TargetType::Field&)> callback) {
|
||||||
if (!t || TREE_CODE(t) != RECORD_TYPE)
|
if (!t || TREE_CODE(t) != RECORD_TYPE)
|
||||||
return false;
|
return false;
|
||||||
@ -285,6 +295,20 @@ bool TargetType::fetch_fields(bool redo) {
|
|||||||
if (!foreach_record_field(m_main_variant, per_field_callback))
|
if (!foreach_record_field(m_main_variant, per_field_callback))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Get struct size
|
||||||
|
|
||||||
|
tree size_tree = TYPE_SIZE(m_main_variant);
|
||||||
|
if (!size_tree || TREE_CODE(size_tree) != INTEGER_CST)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HOST_WIDE_INT size_bits = tree_to_uhwi(size_tree);
|
||||||
|
if (size_bits < 0 || size_bits % 8 != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_size = static_cast<std::size_t>(size_bits / 8);
|
||||||
|
|
||||||
|
// Everything done
|
||||||
|
|
||||||
m_fields = std::move(tmp_fields);
|
m_fields = std::move(tmp_fields);
|
||||||
m_flags |= FLAG_FIELDS;
|
m_flags |= FLAG_FIELDS;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user